Day30-C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\annotation\Proxy
反射
package Basic.src.com.reflect;
import org.junit.Test;
import java.lang.reflect.Method;
public class Test4Method {
@Test
public void testGetMethhod() throws Exception {
//1.反射第一步:先得到Class对象
Class cat = Cat.class;
//2.获取类的全部成员方法
Method[] methods = cat.getDeclaredMethods();
//3.遍历这个数组中的每个方法对象
for (Method method : methods) {
System.out.println(method.getName()+"------------"
+method.getParameterCount()+"------------"
+method.getReturnType());
}
//4.获取某个方法对象
Method run = cat.getDeclaredMethod("run");//拿run(),无参的
System.out.println(run.getName()+"------------"
+run.getParameterCount()+"------------"
+run.getReturnType());
Cat cat1 = new Cat();
run.setAccessible(true);//暴力反射public void run()即使是private也可以访问
Object rs = run.invoke(cat1);//调用方法
System.out.println(rs);//null
System.out.println("====================================");
Method eat = cat.getDeclaredMethod("eat", String.class);
System.out.println(eat.getName()+"------------"
+eat.getParameterCount()+"------------"
+eat.getReturnType());
eat.setAccessible(true);//private String eat(String name)
String es = (String)eat.invoke(cat1,"鱼");
System.out.println(es);//耄耄最爱食:鱼
System.out.println(eat);//private java.lang.String Basic.src.com.reflect.Cat.eat(java.lang.String)
}
}
package Basic.src.com.reflect;
import org.junit.Test;
public class Test5Frame {
@Test
public void save() throws Exception {
Student s1 = new Student("哈基滨", 22, '公', 185.3, "唱跳rap");
Teacher t1 = new Teacher("南北绿豆", 999.9);
//需求:把任意对象的字段名称和其对应的值等信息,保存到文件中去
ObjectFrame.saveObject(s1);
ObjectFrame.saveObject(t1);
}
}
package Basic.src.com.reflect;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
public class ObjectFrame {
//目标:保存任意对象的字段和其数据到文件中去
public static void saveObject(Object obj) throws Exception {
PrintStream ps = new PrintStream(new FileOutputStream("Basic\\src\\data.txt",true));
//1.obj是任意对象,到底有多少个字段要保存。
Class<?> c = obj.getClass();
String cName = c.getSimpleName();
ps.println("------------------"+cName+"------------------");
//2.从这个类中提取它的全部成员变量
Field[] fields = c.getDeclaredFields();
//3.遍历每个成员变量
for (Field field : fields) {
//4.拿到成员变量的名字
String name = field.getName();
//5.拿到这个成员变量在对象中的数据
field.setAccessible(true);//授权
String value = field.get(obj)+"";//+""转为String类型
ps.println(name+"="+value);
}
ps.close();
}
}
注解
注解本质上接口,继承了annotation
package Basic.src.com.annotation;
@MyTest1(aaa="牛魔王",ccc={"HTML","JAVA"})
@MyTest2("孙悟空")//当只有一个未默认化的属性并且叫value,那么value可以省略
public class AnnotationTest1 {
@MyTest1(aaa="铁山公主",bbb=false,ccc={"Python","前端","Java"})
public void test1(){
System.out.println("test1");
}
public static void main(String[] args) {
//执行后会把上面的注解从java文件编译为class后缀的文件
//"C:\Users\Lenovo\Desktop\note\code\JavaSE\out\production\JavaSE\Basic\src\com\annotation\MyTest1.class"
}
}
package Basic.src.com.annotation;
/**
* 自定义注解
*/
public @interface MyTest1 {
String aaa();
boolean bbb() default true;
String[] ccc();
}
package Basic.src.com.annotation;
public @interface MyTest2 {
String value();//特殊属性
int age() default 0;
}
元注解
指的是:修饰注解的注解
@Target @Retention
package Basic.src.com.annotation;
/*
* 元注解
* */
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE,ElementType.METHOD})//当前被修饰的注解只能被用在类上
@Retention(RetentionPolicy.RUNTIME)//只在运行阶段,常用
public @interface MyTest3 {
}
package Basic.src.com.annotation;
/*
* 元注解
* */
@MyTest3
public class AnnotationTest2 {
//@MyTest3报错,这个是成员变量
private String name;
@MyTest3//不报错,这个是方法
public void test(){
}
}
package Basic.src.com.annotation;
import org.junit.Test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
public class AnnotationTest3 {
@Test
public void parseClass() {
//1.先得到class类对象
Class<Demo> c = Demo.class;
//2.解析上面的注解
//判断这个类上面是不是包含了某个注解
if(c.isAnnotationPresent(MyTest4.class)){//MyTest4.class)是填进去的注解类型
MyTest4 myTest4 =
c.getDeclaredAnnotation(MyTest4.class);//就是Demo类里面有没有MyTest4这个注解
System.out.println(myTest4.value());
System.out.println(myTest4.aaa());
System.out.println(Arrays.toString(myTest4.bbb()));
}
Annotation[] da = c.getDeclaredAnnotations();
for (Annotation annotation : da) {
}
}
@Test
public void parseMethod() throws Exception {
//1.先得到class类对象
Class<Demo> c = Demo.class;
Method m = c.getDeclaredMethod("test1");
//2.解析上面的注解
//判断这个"test1"测试方法对象上面是不是包含了某个注解
if(m.isAnnotationPresent(MyTest4.class)){//MyTest4.class)是填进去的注解类型
MyTest4 myTest4 =
c.getDeclaredAnnotation(MyTest4.class);//就是Demo类里面有没有MyTest4这个注解
System.out.println(myTest4.value());
System.out.println(myTest4.aaa());
System.out.println(Arrays.toString(myTest4.bbb()));
}
}
}
package Basic.src.com.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest4 {
String value();
double aaa() default 100;
String[] bbb();
}
package Basic.src.com.annotation;
@MyTest4(value="蜘蛛精",aaa=99.5,bbb={"至尊宝","黑马"})
public class Demo {
@MyTest4(value="哈基滨",aaa=66.6,bbb={"叮咚鸡","大狗嚼嚼嚼"})
public void test1(){
System.out.println("test1");
}
}
package Basic.src.com.annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 目标:模拟Junit框架的设计
*/
public class AnnotationTest4 {
//@MyTest
public void test1(){
System.out.println("test1");
}
@MyTest
public void test2(){
System.out.println("test2");
}
public void test3(){
System.out.println("test3");
}
@MyTest
public void test4(){
System.out.println("test4");
}
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
AnnotationTest4 a = new AnnotationTest4();
//实现启动程序
//1.得到class对象
Class<AnnotationTest4> c = AnnotationTest4.class;
//2.提取这个类中的全部成员方法
Method[] Methods = c.getDeclaredMethods();
//3.遍历这个数组中的每个方法,看方法是是否存在
//触发该方法的执行
for (Method method : Methods) {
if(method.isAnnotationPresent(MyTest.class)){
//说明当前方法上存在该注解,触发该方法执行
method.setAccessible(true);
method.invoke(a);
// Method.invoke() 方法时,括号中第一个参数需要传入的是调用该方法的对象实例(即方法所属的对象),其作用是指定 “在哪个对象上执行当前方法”。
}
}
}
}
package Basic.src.com.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyTest {
}
动态代理
package Basic.src.com.annotation.Proxy;
public class BigStar implements Star {// implements Star是生成代理的约定{
private String name;
public BigStar(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String sing(String name) {
System.out.println(this.name + "正在唱:" + name);
return "thank you!";
}
public void dance(){
System.out.println(this.name+"正在唱跳rap");
}
}
package Basic.src.com.annotation.Proxy;
public interface Star {
//先声明哪些方法要被代理
String sing(String name);
void dance();
}
package Basic.src.com.annotation.Proxy;
public class BigStar implements Star {// implements Star是生成代理的约定{
private String name;
public BigStar(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String sing(String name) {
System.out.println(this.name + "正在唱:" + name);
return "thank you!";
}
public void dance(){
System.out.println(this.name+"正在唱跳rap");
}
}
package Basic.src.com.annotation.Proxy;
public interface Star {
//先声明哪些方法要被代理
String sing(String name);
void dance();
}
package Basic.src.com.annotation.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil {
public static Star createProxy(BigStar bigStar){
Star starProxy = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
new Class[]{Star.class}, new InvocationHandler() {//创建一个实现了 Star 接口的动态代理对象 starProxy
//ProxyUtil 是你自己编写的类(位于 Basic.src.com.annotation.Proxy 包下),它的类加载器是 应用类加载器(AppClassLoader),负责加载用户编写的类(包括你的 Star 接口、BigStar 类等)。
//因此,ProxyUtil 的类加载器与 Star 接口的类加载器是同一个(或存在父子关系,符合双亲委派模型),它们属于同一个 “命名空间”。
@Override //回调方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//我们的代理对象要做的事情
//Object proxy 代理对象本身:starProxy 对象本身
//Method method 调用的什么函数,比如sing dance
//Object[] args 存储了客户端调用代理对象方法时传入的实际参数值,调用的比如sing方法里面的参数
if(method.getName().equals("sing")){
System.out.println("准备话筒,收钱");
//return method.invoke(bigStar,args);//args指的可能是唱哪首歌对应的参数
}else if(method.getName().equals("dance")){
System.out.println("准备场地,收钱");
//return method.invoke(bigStar,args);
}else {
//return method.invoke(bigStar,args);
}
return method.invoke(bigStar,args);//调用BigStar里面的该method对应的方法
}
});//创建代理Proxy.newProxyInstance
/*
* ClassLoader loader,指定一个类加载器,生成一个代理类(固定)
Class<?>[] interfaces,指定生成的代理长什么样,有什么方法,接收多个数组(接口数组里面的方法就可以被接收)
InvocationHandler h指定生成的代理对象要干什么事情,代理干什么事情是由这个决定的
* */
return starProxy;
}
}
package Basic.src.com.annotation.Proxy;
public class TestStar {
public static void main(String[] args) {
BigStar s = new BigStar("杨超越");
Star starProxy = ProxyUtil.createProxy(s);//ProxyUtil类是我们自己编写的,里面有createProxy方法
//创建代理对象,把s传进去,这个工具类就为杨超越类创建了一个代理对象
String rs = starProxy.sing("好日子");//这里的sing方法会调用代理ProxyUtil类中的invoke方法,这里是接口回调
System.out.println(rs);
starProxy.dance();
}
}
改造
package Basic.src.com.annotation.Proxy.Exercise;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil {//代理对应规则
public static UserService createUserService(UserService userService){
UserService userServiceProxy = (UserService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(), new Class[]{UserService.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("login")||method.getName().equals("deleteUsers")||method.getName().equals("selectUsers")){
long startTime = System.currentTimeMillis();
Object rs = method.invoke(userService, args);
long endTime = System.currentTimeMillis();
System.out.println(method.getName()+"方法执行耗时"+(endTime-startTime)+"ms");
return rs;
}else{
Object rs = method.invoke(userService, args);
return rs;
}
}
});
return userServiceProxy;
}
}
package Basic.src.com.annotation.Proxy.Exercise;
public interface UserService {
//登录功能
void login(String name,String password)throws Exception;
//删除用户
void deleteUsers()throws Exception;
//查询用户,返回数组的形式
String[] selectUsers()throws Exception;
}
package Basic.src.com.annotation.Proxy.Exercise;
public class UserServiceimpl implements UserService {
@Override
public void login(String name, String password) throws Exception {
if("admin".equals(name) && "123456".equals(password)){
System.out.println("登录成功,欢迎光临本系统");
}else{
System.out.println("登录失败,用户名或密码错误");
}
Thread.sleep(1000);
}
@Override
public void deleteUsers() throws Exception {
System.out.println("成功删除了一万个用户");
Thread.sleep(1500);
}
@Override
public String[] selectUsers() throws Exception {
System.out.println("查询出了三个用户");
String[] names = {"张三","李四","王五"};
Thread.sleep(500);
return names;
}
}
package Basic.src.com.annotation.Proxy.Exercise;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws Exception {
//1.创建用户业务对象
//UserService userService = new UserServiceimpl();//接口是 “类” 的一种特殊形式,这个没有计时功能
UserService userService = ProxyUtil.createUserService(new UserServiceimpl());
//2.调用用户业务的功能
userService.login("admin","123456");//下面都是代理的代码
System.out.println("===========================");
userService.deleteUsers();
System.out.println("===========================");
String[] names = userService.selectUsers();
System.out.println("查询到的用户是:"+ Arrays.toString(names));
System.out.println("===========================");
}
}

浙公网安备 33010602011771号