你的位置:首页 > Java教程

[Java教程]SpringAOP之动态代理


一、动态代理:

      1.在原有的静态代理的基础上进一步的完善,由于静态代理中,重复写了相同的代码使得代码的整体结构显得冗余,而且还不同的核心类还需要有不用的代理类,是写死了的具体的类。所以需要使用动态代理来代替静态代理。

      2.具体实例:

        ⑴、业务介绍:

          假定高三学生为核心类,学生的家人是代理类。高三学生需要做的核心业务有:在家学习(studyAtHome)、在学校学习(studyAtHome);家人需要做的非核心业务为:准备饭菜(买、洗、炒、煮饭)。准备补品(购买、熬制、加佐料)。 

        ⑵、创建一个高三学生接口:G3Student

package aop_002;//首先定义一个接口,用来高三学生来是实现,//在这个接口中声明一个在家学习和一个在学校学习的方法public interface G3Student {  public void studyAtHome(String core);  public void studyAtSchool(String core);  }

 

          ⑶、创建一个高三学生(G3Student_boy),实现高三学生接口(G3Student),这个高三学生的类就是核心类。

package aop_002;/* * 本例演示的是动态代理*///定义一个高三学生的类(目标对象、核心对象、target对象),实现了高三学生的接口。public class G3Student_boy implements G3Student {    //高三学生 的第一个业务流程:在家学习  public void studyAtHome(String core) {        //核心的事情是在家学习。    System.out.println(core+"在HOME学习");      }  //高三学生 的第二个业务流程:在学校学习  public void studyAtSchool(String core) {//核心的事情是在家学习。    System.out.println(core+"在SCHOOOL学习");  
  }}

 

 

          ⑷、创建一个高三学生的代理类(G3Student_handler),并且实现了InvocationHandler接口

package aop_002;

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class G3Student_handler implements InvocationHandler { private Object g3Stu; public G3Student_handler(Object g3Stu) { this.g3Stu = g3Stu; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //调用代理的在核心对象处理核心业务之前的方法 before(); //核心对象的核心方法 Object returnValue = method.invoke(g3Stu, args); //调用代理的在核心对象处理核心业务之后的方法 after(); return returnValue; } private void before(){ //这个是代理(G3Student_handler)准备饭菜的需要做的流程: System.out.println("代理:准备买菜"); System.out.println("代理:准备洗菜"); System.out.println("代理:准备炒菜"); System.out.println("代理:准备煮饭"); System.out.println("-----------------"); } private void after(){ //这个是代理(G3Student_handler)准备补品的需要做的流程: System.out.println("-----------------"); System.out.println("代理 :购买补品"); System.out.println("代理 :熬制部品"); System.out.println("代理 :加入佐料"); System.out.println(); } }

 

           ①、其中,和静态代理不同的是,动态代理的代理类中定义了一个以Object类型的属性,而静态代理定义的是具体的G3Student的接口类型的属性。所以,动态代理这样定义保证了,这个代理可以带不同的个核心类如:G3Student_boy、G3Student_girl。

           ②、这句代码意思:自动调用传入的核心类对象(G3Student_boy)的方法,并且传入参数args,返回一个Object类型的值。具体是调用什么方法,传入什么参数,都不需要我们具体关注,只需写上这条代码,并且把返回值返回即可

            

          ⑸、创建一个测试类Test:

package aop_002;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;public class Test {  public static void main(String[] args) {        G3Student boy = new G3Student_boy();             InvocationHandler handler1 = new G3Student_handler(boy);     
     G3Student g3boy = (G3Student)Proxy.newProxyInstance(boy.getClass().getClassLoader(), boy.getClass().getInterfaces(),handler1); g3boy.studyAtSchool("小明"); g3boy.studyAtHome("小明"); }}

            ①、首先,需要创建一个高三学生对象,其次需要创建一个代理类对象,最后使用Proxy创建一个高三学生对象,再调用方法即可。

          ②、可能有的人会问,为什么不直接使用第一次创建的高三学生对象直接调用方法呢?如果使用第一次创建的高三学生对象直接调用方法,那么就没有代理做的事情显示,所以应该时候用Proxy创建的高三学生对象,Proxy等于是高三学生对象和代理对象进行一次整合,使它们两个有机结合在一起,各自做各自的事情。

          测试结果:

                            

 


      谢谢浏览!