spring-反射动态代理

Posted xiongchang95

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring-反射动态代理相关的知识,希望对你有一定的参考价值。

主要是对上一篇文章中涉及到的点做补充,欢迎指正!

1、  java反射知识-Spring IOC 依赖注入

  Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

  Java中有个继承至Object类的Class类,其对象用于表达Java程序运行时的所有类和接口,也用来表达enum、array、primitive Java types(boolean, byte, char, short, int, long, float, double)以及关键词void。当一个class被加载,或当加载器(class loader)的defineClass()被JVM调用,JVM 便自动产生一个Class 对象。【可以理解为一个类就是一个Class对象

  Java语言允许通过程序化的方式间接对Class对象进行操作,Class文件由类加载器在编译期装载后,在方法区中将形成一份描述Class对象结构的元信息数据,在堆中生成一个指向该元信息数据的Class对象,通过Class对象可以获知.class结构信息:如构造函数、属性和方法等。

  Java允许用户借由这个Class对象间接调用其功能,这就为使用程序化方式操作Class对象开辟了途径。

  反射优势在于:当我们的程序在运行时,需要动态的加载一些类这些类可能之前用不到所以不用加载到jvm,而是在运行时根据需要才加载,如果使用非反射,则需要修改代码,重新编译和运行,耗时耗资源。

            技术分享图片

            技术分享图片

2、  java动态代理-Spring AOP

  为其他对象提供一种代理以控制对这个对象的访问。实质就是将你要使用的类,重新生成一个子类或本类,这样框架就可以利用这个新生成的类做一些事情,比如在该类的方法前后加一些代码。这样的话,不用修改任何已经编写好的代码,只要使用代理就可以灵活的加入任何东西,将来不喜欢了,不用也不会影响原来的代码。动态代理是设计模式当中代理模式的一种。

  JDK 1.3以后,Java提供了动态代理的技术,允许开发者在运行期创建接口的代理实例。JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。其中InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编织在一起。而Proxy用来动态创建一个代理对象的类。

  每一个动态代理类handler都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler, 当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。通过 Proxy.newProxyInstance 创建的代理对象是在jvm运行时动态生成的一个对象,它并不是我们的InvocationHandler类型,

public interface PersonDao {

         public void say();

}

 

public class PersonDaoImpl implements PersonDao{

         @Override

         public void say() {System.out.println("time to eat");}

}

 

public class PersonHandler implements InvocationHandler {

 

         private Object obj;

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

        

         @Override

         public Object invoke(Object proxy, Method method, Object[] args)

                          throws Throwable {        

                  System.out.println("before");

      // args表示say函数所需要的实际参数

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

                  System.out.println("after");

                  return result;

         }

}

 

public class PersonTest {

         @Test

         public void test(){

                  PersonDao pDao = new PersonDaoImpl();

                  PersonHandler handler = new PersonHandler(pDao);  

                  PersonDao proxy = (PersonDao)Proxy.newProxyInstance                 (pDao.getClass().getClassLoader(),

                pDao.getClass().getInterfaces(),

                handler);

                  proxy.say();

         }

}

以上是关于spring-反射动态代理的主要内容,如果未能解决你的问题,请参考以下文章

spring-反射动态代理

动态代理在Spring中的应用

什么是反射技术?什么是静态代理?什么是动态代理?什么是aop

java反射机制动态代理初探

Spring容器AOP的理解

Spring AOP动态代理实现,解决Spring Boot中无法正常启用JDK动态代理的问题