`
crmjava
  • 浏览: 7458 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

chapter03 Spring的AOP

阅读更多

chapter03 SpringAOP

一、AOP(Aspect-oriented programming,面向切面编程)

  什么是AOP

  定义:将程序中的交叉业务逻辑提取出来,封装成切面然后由AOP容器的功能织入到具体的业务模块当中,然后生成一个代理对象的过程。

例如:安全,事务,日志等都属于交叉业务逻辑。他们的特点是都是通用的并且与具体的业务逻辑无关。他们往往与具体的业务逻辑交织在一起、

 

切面------织入----->目标对象-------生成------>AOP代理

 

AOP实现的方式:

1.使用特殊的编译器,直接将切面代码写入到目标对象的字节码当中,它的优点是速度快,实现困难 AspectJ

2.在目标类加载是将切面代码织入到目标对象当中,需要实现一个classloader

3.SpringAOP实现方式:利用动态代理机制

二、AOP核心概念

  1Aspect(切面)

  切面,是对交叉业务逻辑的统称。

  2Joinpoint(连接点)抽象的概念

  连接点,指切面可以织入到目标对象的位置(方法,属性等)。

  3Advice(通知)

  通知,指切面的具体实现。

  4Pointcut(切入点)

  切入点,指通知应用到哪些类的哪些方法或属性之上的规则。(即切面具体织入的位置)

  5Introduction(引入)

  引入,指动态地给一个对象增加方法或属性的一种特殊的通知。

  6Weaving(织入)

  织入,指将通知插入到目标对象。

  7Target(目标对象)

  目标对象,指需要织入切面的对象。

  8Proxy(代理对象)

  代理对象,指切面织入目标对象之后形成的对象。

AOP采用代理模式实现的原理:

1.静态代理模式:

package aop1;

//目标对象或叫目标类

public class CustomerService implements ICustomerService{

       @Override

       public void register() {

              System.out.println("register");      

       }

}

package aop1;

//代理接口

public interface ICustomerService {

   public void register();

}

package aop1;

import java.util.Date;

//代理类

public class CustomerProxy implements ICustomerService{

    private ICustomerService isc;

       public CustomerProxy() {

              super();

       }

       public CustomerProxy(ICustomerService isc) {

              super();

              this.isc = isc;

       }

       @Override

       public void register() {

              //交叉业务(切面代码),由代理类实现

              System.out.println("current time is :"+new Date());

              //核心业务逻辑,由目标对象来实现

              isc.register();

       }

}

package aop1;

public class Test {

       /**

        * @param args

        * 客户端

        * 静态代理模式

        */

       public static void main(String[] args) {

          ICustomerService target=new CustomerService();

          ICustomerService proxy=new CustomerProxy(target);

          //上面两行代码应该交给工厂去做。我们不关心得到的是目标还是代理对象

          //spring当中它是交给spring容器做的

          proxy.register();

       }

}

 

2.动态代理模式:

package aop2;

//目标对象或叫目标类

public class CustomerService implements ICustomerService{

   @Override

       public void register() {

              System.out.println("register");      

       }

}

package aop2;

//代理接口

public interface ICustomerService {

   public void register();

}

package aop2;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.util.Date;

//切面的代码(交叉业务逻辑),接口的作用是将切面代码织入到目标对象当中

public class LogInvocationHandler implements InvocationHandler{

    private Object target;//因为这段切面不只是织入到一个目标类中

       public LogInvocationHandler() {

              super();

       }

       public LogInvocationHandler(Object target) {

              super();

              this.target = target;

       }

       @Override

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

       //method代表目标对象的一个方法,args目标对象方法参数的值

                     throws Throwable {

              //切面代码

              System.out.println("execute invoke" + new Date());

              //执行目标对象里面的方法

              System.out.println("method"+method);

              Object proxy1=method.invoke(target, args);

              System.out.println(proxy1);

              return proxy1;

       }

  

}

package aop2;

public class Test {

   /**

        * @param args

        * 客户端

        * 动态代理模式

        */

       public static void main(String[] args) {

        ICustomerService target=new CustomerService();

        ICustomerService proxy=(ICustomerService) java.lang.reflect.Proxy.newProxyInstance

        (target.getClass().getClassLoader(),

                      target.getClass().getInterfaces(),

                             new LogInvocationHandler(target));

        //参数1目标对象的类加载器,参数2目标对象所实现的业务接口,参数3切面

        proxy.register();

       }

}

 

三、Spring AOP原理

  采用动态代理模式。

 

  Spring AOP采动态代理的过程:

(1) 将切面使用动态代理的方式动态织入到目标对象(被代理类),形成一个代理对象;

(2) 目标类如果没有实现代理接口,那么Spring会采用CGLib来生成代理对象,该代理对象是目标对象的子类;此时的目标类不能是final的类。如果实现了业务接口,Spring会直接使用jdk当中的Proxy生成代理

(3) 目标对象如果是final类,并且也没实现代理接口,就不能运用AOP

 

四、Spring的通知

1Spring的通知类型

(1) MethodBeforeAdvice

  类全名:org.springframework.aop.MethodBeforeAdvice

  目标方法调用之前,做处理。

  不能够改变返回值

  不能够改变目标方法的流程,也不能中断流程的处理过程(除非抛出异常)

(2) AfterReturningAdvice

  类全名:org.springframework.aop.AfterReturningAdvice  

在方法调用之后,做处理。

  不能够改变返回值

  不能够改变目标方法的流程,也不能中断流程的处理过程(除非抛出异常)

(3) MethodInterceptor:拦截器

  类全名:org.aopalliance.intercept.MethodInterceptor

在方法调用之前以及之后,做处理。

  可以改变返回值,也可以改变流程。

(4) ThrowsAdvice:异常处理通知

  类全名:org.springframework.aop.ThrowsAdvice

在方法抛出异常后,做处理。

  当该通知处理完异常后,会简单地将异常再次抛出给目标调用方法。

(5)自定义的通知,

Advisor

    PointcutAdvice结合到一起。

2、配置过程:

  1)配置目标对象

  2)配置通知

  3)利用ProxyFactoryBean将通知织入到目标对象,形成一个动态代理对象

  4)客户端使用动态代理来访问目标对象的方法。

 

  在默认情况下,通知会应用到所有的方法之上。

Pointcut

根据方法和类决定在什么地方织入通知

  Advisor

  PointcutAdvice结合到一起。

 

  自定义切入点:

  步骤:

  1)实现org.springframework.aop.ClassFilter

  2)实现org.springframework.aop.MethodMatcher

  3)实现org.springframework.aop.Pointcut

  4)实现org.springframework.aop.PointcutAdvisor

  注意:

  在此可定义

  private Advice advice;

  private Pointcut pointcut;

  在配置文件中,将自定义的切入点与通知绑订到一起

  5)利用ProxyFactoryBeanadvisor织入到目标对象

 

ProxyFactoryBean的作用:

  依照配置信息,将切面应用到目标对象,生成动态代理对象。

  (1) Spring只支持方法连接点,不支持属性连接点。

(原因是Spring AOP采用的是动态代理模式,而动态代理本身就是在方法调用前加入代码。)

  (2) Spring只在运行时,将切面织入到目标对象。

(有些AOP实现,可以在编译是织入切面到目标对象。)

Injecting Advicecon’t d

<bean id=”registerService’ class=”org.springframework.aop.framework.ProxyFactoryBean”>

         <property name=”proxyInterfaces”>  目标对象实现的接口

          (如果没有定义接口,则所有方法使用CGLib

             <value>aop.RegisterService</value>

          </property>

          <property name=”target”>    目标对象

             <ref local=”registerServiceTarget”/>

          </property>

          <property name=”interceptorNames”>需要织入到目标对象的切面

              <list>

               <value>logAdvice</value>

               <value>throwsAdvice</value>

              </list>

          </property>

</bean>                                                                     

五、切入点(Pointcut

  1Pointcut<interface>

  切入点是指通知/切面可以应用到哪些类,哪些方法之上。

  Pointcut API

  Pointcutorg.springframework.aop.Pointcut

对某些类某些方法应用切面。

  Classfilterorg.springframework.aop.ClassFilter

用来过滤类(哪些类可以应用切面)

  MethodMatherorg.s

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics