Java反射和代理模式

1.Java反射机制

    静态语言(强类型语言):
    静态语言是在编译时变量的数据类型既可确定的语言,在使用变量之前必须声明数据类型。
    例如:C、C++、Java
    动态语言 (弱类型语言)
    动态语言是在运行时才确定数据类型的语言,程序运行时课改变结构和数据类型。

Java反射机制

 程序运行时,对于任意一个类,都能知道这个类的所有方法和属性;对于任意一个对象,都能够调用它的方法和属性
 Class类
 注意:当Java虚拟机载入一个类的时候, 它就会自动创建一个Class类的实例来表示这个类,该实例中包含了完整的类的结构信息,这个对象像一面镜子一样将类的结构展示给我们,所以我们成为"反射"。

Java反射实现:
利用Class实例实现反射机制:因为Class类的构造函数是Private,不能通过new的方式来创建Class实例,只有JVM有权力一般有三种方式:
 1.类名.Class
 2.getClass()
 3.通过全类名获取,用的较多
 注意:每一个类只对应一个`在这里插入代码片`
        Class cc=Class.forName("cn.gok.beans.User");
        System.out.println("获得类名(全名):"+cc.getName());
        System.out.println("获得类名(名字):"+cc.getSimpleName());

        Object obj=new User(12,"swag","123");
//        获取类的属性
        Field[] fields =cc.getFields();
        for (Field field : fields){
            System.out.println(field.getName());//获取属性名
        }
                /*
         * 类的反射也可以获得方法
         * */
        //获得指定方法
        Method method = cc.getDeclaredMethod("eate",String.class);
        method.invoke(obj,"花生米");//执行该方法
        System.out.println("end..............");

实体类

@Table("user")
public class User {
    @Column("id")
    private Integer id;//用户ID
    @Column("username")
    private String name;//用户名
    @Column("password")
    private String psw;//用户密码
     String phone;//电话号码
    /*
     * 构造函数
     * */
//    无参构造
    public User() {
    }
//  有参构造
    public User(Integer id, String name, String psw) {
        this.id = id;
        this.name = name;
        this.psw = psw;
    }
    /*
    * 吃的方法
    * */
    public void eate() {
        System.out.println("早餐:面包+牛奶");
    }
    public void eate(String s) {
        System.out.println("早餐:面包+牛奶"+"   "+s);
    }

自定义注解

@Target(ElementType.FIELD)//作用在字段
@Retention(RetentionPolicy.RUNTIME)//运行时注解,可以通过类的反射获取
public @interface Column {
    String value();
}
@Target(ElementType.TYPE)//作用在类或接口
@Retention(RetentionPolicy.RUNTIME)//运行时注解,可以通过类的反射获取
public @interface Table {
    String value();//当注解只有一个变量时 变量名必须为value
}

测试

    public void test2() throws Exception {
        User user=new User(1,"dsk","qwer");

        //获得类信息
        Class cc=user.getClass();
//        cc.isAnnotationPresent(Table.class):判断是否有该注解
        System.out.println(cc.isAnnotationPresent(Table.class));
//       cc.getAnnotation(Table.class) 获得该注解
      Table table= (Table) cc.getAnnotation(Table.class);
        System.out.println(table.value());
    }

2.了解静态代理实现

Java设计模式–代理模式
为其他对象提供一种代理,从而实现对这个对象的访问控制。在某些情况下,一个对象不能直接引用另一个对象,代理对象可以在客户端和目标对象之间起到中介的作用。
(代理模式用来扩展新功能,在不修改源码的情况下,使用代理模式需要一个代理对象)
代理模式的静态代理的实现
1.创建一个接口(JDK的代理都是面向接口的)
2.创建具体实现类来实现这个接口
3.再创建一个代理类实现这个接口,具体实现类的方法中需要将接口中定义的方法的业务逻辑实现,而代理类中的方法只要调用具体类中的方法就行
接口

public interface UserDao {
//  注册用户
    public int registUser(User user);
//    删除用户
    public int delUser(int id);
}

实现类

public class UserDaoImpl implements UserDao {
    @Override
    public int registUser(User user) {
        System.out.println("调用数据库添加用户");
        return 0;
    }

    @Override
    public int delUser(int id) {
        System.out.println("调用数据库删除用户:"+id);
        return 1;
    }
}

代理实现类

public class UserDaoProxy implements UserDao {
    private UserDaoImpl userDaoImpl= new UserDaoImpl();
    @Override
    public int registUser(User user) {
        return 0;
    }

    @Override
    public int delUser(int id) {
        System.out.println("代理增强");
        int out=userDaoImpl.delUser(id);
        return out;
    }
}

静态代理的缺陷:使用静态代理,可以知道每一个代理类只能为一个接口服务,如果有多个接口则需要多个代理类与之对应,那么在开放过程中会产生许多的代理,不利于代码的维护,所以引出了动态代理。

3.动态代理的方式

动态代理分为两种,JDK的代理和CGLB的动态代理
1.JDk的动态代理依赖具体的接口,需要代理类有对应的接口类型
2.CGLB代理不依赖具体的接口,功能更加强大,被代理类可以是一个没有接口的类,需要实现
MethodInterceptor接口

public class JDKProxy implements InvocationHandler {
    private Object obj;

    public JDKProxy(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(proxy.getClass().getName());

        System.out.println("传入参数:"+ JSON.toJSONString(args));
        System.out.println("JDK 代理之前");


        Object o= method.invoke(obj,args);


        return o;
    }


}
public class TestCGLIB implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("CGLIB执行前!");

        Object out=methodProxy.invokeSuper(o,objects);

        System.out.println("CGLIB执行之后!");
        return out;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值