Spring AOP基础

  • AOP开垦术语
  • Spring支持的advice类型
  • Spring中开创代理对象
    • ProxyFactory
    • ProxyFactoryBean
  • Spring对切面包车型客车帮衬
  • xxxAutoProxyCreator自动代理创造器

Spring帮忙三种档案的次序的升高或布告(Advice):
Before(方法实施前) org.apringframework.aop.MethodBeforeAdvice
AfterReturning(方法重返后) org.springframework.aop.AfterReturningAdvice
After-throwing(非常抛出后) org.springframework.aop.ThrowsAdviceArround
围绕,即方法前后 org.aopaliance.intercept.MethodInterceptor
引介,不常用 org.springframework.aop.IntroductionInterceptor

示例:

  • Joinpoint:程序中某些特定的任务,在Spring中仅帮助办法作为Joinpoint,仅能在章程调用前后织入巩固逻辑
  • Pointcut:一组Jointpoint,三个Pointcut能够相配多少个Jointpoint
  • Advice:织入到Target上的一段代码
  • Target:要求代理的指标类对象
  • Weaving:拦截到Joinpoint后,把Advice增加到Jointpoint上的历程
  • Proxy:被AOP巩固后生成的代理对象
  • Aspect/Advisor:Jointpoint/Pointcut和Advice的结合
package spring4;

/**
 * Created by weixin:javajidi_com.
 * 业务逻辑接口
 */
public interface Service {

    void print(String str);

}


package spring4;

/**
 * Created by weixin:javajidi_com.
 */
public class ServiceImpl implements Service {

    public void print(String str) {
        System.out.println("我是业务方法"+str);
    }
}


package spring4.aop;

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

/**
 * Created by weixin:javajidi_com.
 */
public class AfterAdvice implements AfterReturningAdvice {

    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
        System.out.println("AfterAdvice方法执行完成了");
        System.out.println(method.getName()+";"+o1.getClass());
    }
}


package spring4.aop;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

/**
 * Created by weixin:javajidi_com.
 * 方法执行前的逻辑,称前置通知
 */
public class BeforeAdvice implements MethodBeforeAdvice{
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("BeforeAdvice方法执行前");
        System.out.println(method.getName()+";"+o.getClass());
    }
}


package spring4.aop;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * Created by weixin:javajidi_com.
 */
public class RoundAdvice implements MethodInterceptor {

    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("Roundadvice方法执行前");
        System.out.println(methodInvocation.getArguments()[0]);//可以获取目标方法的参数值
        Object result=methodInvocation.proceed();//调用目标对象的方法
        System.out.println("RoundAdvice方法执行完成了");
        return result;
    }
}


package spring4.aop;

import org.springframework.aop.framework.ProxyFactory;
import spring4.Service;
import spring4.ServiceImpl;

/**
 * Created by weixin:javajidi_com.
 */
public class Test {

    public static void main(String[] arg){
        Service service=new ServiceImpl();//
        //使用代理工厂为目标对象创建代理,并织入我们自己的advice逻辑
        ProxyFactory proxyFactoryBean=new ProxyFactory();
        proxyFactoryBean.setTarget(service);//设置目标对象
        proxyFactoryBean.addAdvice(new BeforeAdvice());//为目标对象织入增强
        proxyFactoryBean.addAdvice(new AfterAdvice());
        proxyFactoryBean.addAdvice(new RoundAdvice());
        Service proxy=(Service)proxyFactoryBean.getProxy();
        proxy.print("test");
    }
}

运维结果:

  • org.springframework.aop.MethodBeforeAdvice,前置布告:在指标业务方法前被调用
BeforeAdvice方法执行前
print;class spring4.ServiceImpl
Roundadvice方法执行前
test
我是业务方法test
RoundAdvice方法执行完成了
AfterAdvice方法执行完成了
print;class spring4.ServiceImpl

即便通过xml配置,大家能够利用ProxyFactoryBean

public class BusinessBeforeAdvice implements MethodBeforeAdvice { /** * @param method 目标类方法 * @param args 目标类方法参数 * @param target 目标类实例 * @throws */ public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("BusindessBeforeAdvice starting..."); System.out.println("目标类:" + target.getClass().getName() + "." + method.getName; }}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="beforeAdvice" class="spring4.aop.BeforeAdvice"/>
    <bean id="afterAdvice" class="spring4.aop.AfterAdvice"/>
    <bean id="roundAdvice" class="spring4.aop.RoundAdvice"/>
    <bean id="service" class="spring4.ServiceImpl"/>
    <bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

        <property name="interceptorNames">
            <list>
                <value>beforeAdvice</value>

                <value>afterAdvice</value>

                <value>roundAdvice</value>
            </list>
        </property>
        <property name="target" ref="service"></property>
    </bean>

</beans>

package spring4.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring4.Service;

/**
 * Created by weixin:javajidi_com.
 */
public class Test {

    public static void main(String[] arg){
//        Service service=new ServiceImpl();
//        //使用代理工厂为目标对象创建代理,并织入我们自己的advice逻辑
//        ProxyFactory proxyFactoryBean=new ProxyFactory();
//        proxyFactoryBean.setTarget(service);//设置目标对象
//        proxyFactoryBean.addAdvice(new BeforeAdvice());//为目标对象织入增强
//        proxyFactoryBean.addAdvice(new AfterAdvice());
//        proxyFactoryBean.addAdvice(new RoundAdvice());
//        Service proxy=(Service)proxyFactoryBean.getProxy();
//        proxy.print("test");

        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("classpath:spring.xml");
        Service service=applicationContext.getBean("serviceProxy",Service.class);
        service.print("test");
    }
}
  • org.springframework.aop.AfterReturningAdvice,前置布告:在指标业务方法后被调用

在前方介绍各条巩固时,大家也许未有理会到几个难点:巩固被织入到指标类的具备办法中。

设若我们期待有选用地织入到对象类有个别特定的不二法门中,就必要运用切点举行指标连接点的一向了。描述连接点是举办AOP编制程序最重大的一项职业。巩固提供了连接点方位音信:如织入到方法前边、后边等,而切点进一步描述织入到怎么类的什么方法上。

public class BusinessAfterAdvice implements AfterReturningAdvice { /** * @param returnValue 目标类方法返回结果 * @param method 目标类方法 * @param args 目标类方法参数 * @param target 目标类实例 * @throws */ public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("BusindessBeforeAdvice starting..."); System.out.println("目标类:" + target.getClass().getName() + "." + method.getName; System.out.println("返回值类型:" + returnValue.getClass().getName; }}

Spring通过org.springframework.aop.Pointcut接口描述切点,Pointcut由ClassFilter和MethodMatcher构成。它通过ClassFilter定位到一点特定类上,通过MethodMatcher定位到一点特定措施上,那样Pointcut就有着了描述有些类的有些特定措施的力量。

  • org.aopalliance.intercept.MethodInterceptor,环绕公告:在指标业务方法前后被调用

Spring提供了六系列型切点:

·静态方法切点:org.springframework.aop.support.StaticMethodMatcherPointcut是静态方法切点的肤浅基类,默许情状下它非常全部的类。 StaticMethodMatcherPointcut包罗三个主要的子类,分别是NameMatchMethodPointcut和AbstractRegexpMethodPointcut,后面一个提供轻便字符串相配方法签字,而后人使用正则表明式匹配方法具名;

public class BusinessAroundAdvice implements MethodInterceptor { /** * @param 封装目标类所有信息 */ @Override public Object invoke(MethodInvocation invocation) throws Throwable { // 方法参数 Object[] arguments = invocation.getArguments(); String name =  arguments[0]; System.out.println("参数:" + name); System.out.println; Object obj = invocation.proceed(); System.out.println; return obj; }}

·动态方法切点:org.springframework.aop.support.DynamicMethodMatcherPointcut是动态方法切点的抽象基类,暗许意况下它万分全体的类。 DynamicMethodMatcherPointcut类已经过时,能够动用DefaultPointcutAdvisor和DynamicMethodMatcherPointcut动态方法相称器代替之;

  • org.springframework.aop.ThrowsAdvice,相当布告:在对象业务方法抛出拾壹分是被调用

·注脚切点:org.springframework.aop.support.annotation.AnnotationMatchingPointcut完毕类表示注脚切点。使用AnnotationMatchingPointcut帮助在Bean中央政府机关接通过JDK5.0解说标签定义的切点;

·表明式切点:org.springframework.aop.support.ExpressionPointcut接口主假设为着辅助AspectJ切点表达式语法而定义的接口;

public class BusinessThrowsAdvice implements ThrowsAdvice { /** * ThrowsAdvice没有定义任何方法,此接口为标记接口<br/> * 方法名必须定义为 afterThrowing() * 可选[Method method, Object[] args, Object target] * 最后一个参数必须为Throwable或子类 * * @param method * @param args * @param target * @param ex */ public void afterThrowing(Method method, Object[] args, Object target, Exception ex) { System.out.println("方法名称:" + method.getName; System.out.println("异常信息:" + ex.getMessage; }}

·流程切点:org.springframework.aop.support.ControlFlowPointcut完成类表示调整流程切点。ControlFlowPointcut是一种极其的切点,它依照程序执行饭店的新闻查阅目的措施是不是由某一个主意直接或直接发起调用,以此推断是还是不是为协作的连接点;

  • org.springframework.aop.IntroductionInterceptor,引导介绍文告:在目的类中增加新的艺术或性质

·复合切点:org.springframework.aop.support.ComposablePointcut实现类是为开创多个切点而提供的福利操作类。它兼具的办法都回去ComposablePointcut类,那样,大家就能够使用链接表明式对其进展操作,形如:
Pointcut pc=new ComposablePointcut().union(classFilter).intersection(methodMatcher).intersection(pointcut)

日前早就表达过,切面正是由切点和进步组成。由于巩固既蕴涵横切代码,又富含部分的连接点新闻(方法前、方法后等的方向音信),所以大家得以仅经过压实类生成三个断面。但切点仅表示指标类连接点的片段音讯(类和措施的定点),所以唯有切点,大家无法制作出三个断面,必得结合抓实才干构建出切面。

public interface IIntroductionMethod { public void thisMethod();}public class BusinessIntroductionAdvice extends DelegatingIntroductionInterceptor implements IIntroductionMethod { private static final long serialVersionUID = -8213962377263745715L; /** * 通过实现接口方法,在目标类织入新的方法 */ @Override public void thisMethod() { System.out.println("引介通知的方法"); } @Override public Object invoke(MethodInvocation mi) throws Throwable { System.out.println("BusinessIntroductionAdvice starting ..."); return super.invoke; }}

Spring使用org.springframework.aop.Advisor接口表示切面包车型地铁定义,一个断面同不时候包蕴横切代码和连接点音讯。

  • 如上5种等级次序,独有MethodInterceptor在aopalliance包中任何都在spring包中
  • IntroductionInterceptor通过在对象类中扩展方法,来增长指标类,在spring中承袭DelegatingIntroductionInterceptor, DelegatingIntroductionInterceptor完毕了IntroductionInterceptor,通过落到实处贰个自定义接口IIntroductionMethod,为对象类增加新的法子
  • 以上5中通报使用的事体接口和促成类

·Advisor:代表日常切面,它仅富含三个Advice,咱们说过,因为Advice包含了横切代码和连接点的消息,所以Advice本人就是三个回顾的切面,只然则它意味着的横切的连接点是享有目的类的具备办法,因为那一个横切面太普及,所以平时不会平昔动用;

·PointcutAdvisor:代表全体切点的切面,它包括Advice和Pointcut多少个类,那样大家就可以通过类、方法名以及艺术方面等新闻灵活地定义切面包车型大巴连接点,提供更具适用性的切面。

public interface IBusiness { public void doSomething(); public String doReturn(); public void hello(String name); public void thr0ws();}public class BusinessImpl implements IBusiness { public void doSomething() { System.out.println("BusinessImpl.doSomething; } public String doReturn() { return "doReturn"; } @Override public void hello(String name) { System.out.println("hello " + name); } @Override public void thr0ws() { throw new RuntimeException("ThrowsAdvice"); }}

PointcutAdvisor主要有6个有血有肉的兑现类,分别介绍如下:

  • ProxyFactory:Spring对代理对象的创造进行了抽象和包装,使用ProxyFactory成立代理对象,使创办进度越是简便易行
  • 创建jdk代理

·DefaultPointcutAdvisor:最常用的断面类型,它能够通过自由Pointcut和Advice定义三个断面,独一不协理的是引导介绍的断面类型,日常能够透过扩大该类完结自定义的断面;

·NameMatchMethodPointcutAdvisor:通过此类能够定义按章程名定义切点的断面:

 @Test public void beforeAdvice4Jdk() { IBusiness bus = new BusinessImpl(); BeforeAdvice advice = new BusinessBeforeAdvice(); // spring提供的代理工厂 ProxyFactory pf = new ProxyFactory(); pf.setTarget; pf.addAdvice; pf.setInterfaces(bus.getClass().getInterfaces;// 使用jdk代理,指定接口 IBusiness proxy = (IBusiness) pf.getProxy(); proxy.doSomething(); System.out.println(proxy.getClass().getName; }

·RegexpMethodPointcutAdvisor:对于按正则表达式相称方法名张开切点定义的断面,可以通过扩张该兑现类实行操作。 RegexpMethodPointcutAdvisor允许顾客以正则表明式方式串定义方法相配的切点,在那之中间通过JdkRegexpMethodPointcut构造出正则表明式方法名切点。

  • 创建cglib代理

·StaticMethodMatcherPointcutAdvisor:静态方法相称器切点定义的切面,暗许意况下,相配全体的靶子类;

·AspecJExpressionPointcutAdvisor:用于Aspecj切点表明式定义切点的切面。

@Test public void beforeAdvice4Cglib() { IBusiness bus = new BusinessImpl(); BeforeAdvice advice = new BusinessBeforeAdvice(); ProxyFactory pf = new ProxyFactory(); pf.setTarget; pf.addAdvice; pf.setOptimize;// 针对代理进行优化,接口也会使用cglib IBusiness proxy = (IBusiness) pf.getProxy(); proxy.doSomething(); System.out.println(proxy.getClass().getName; }

·AspecJPointcutAdvisor:用于AspecJ语法定义切点的断面。

  • ProxyFactoryBean:配置文件方式

那些Advisor的落到实处类,都能够在Pointcut中找到对应物,实际上,它们都以经过扩大对应Pointcut达成类并贯彻PointcutAdvisor接口举行定义。别的,Advisor都完毕了org.springframework.core.Ordered接口,Spring将依照Advisor定义的逐个决定织入切面包车型客车依次。

咱俩由此选用RegexpMethodPointcutAdvisor来掌握什么运用。

 <bean ></bean> <bean ></bean> <!-- target-ref:被代理的对象,也就是target对象 proxyInterfaces:被代理对象的接口,也就是target接口 interfaces:proxyInterfaces的别名 interceptorNames:advice、advisor实现类,具体的横切逻辑实现 proxyTargetClass:true=对target进行cglib代理,不使用jdk,=true时忽略proxyInterfaces配置 optimize:true:强制使用cglib singletion:返回代理对象是否为单例,默认单例 --> <bean p:proxyInterfaces="exam.aop.interfaces.IBusiness" p:interceptorNames="buinessBeforeAdvice" p:target-ref="businessImpl"></bean>

RegexpMethodPointcutAdvisor表示通过正则表达式实行切点描述的断面,它有三个pattern属性用来钦赐加强要选择到何等类的什么方法,也能够由此patterns属性内定多个表达式进行相配。有贰个advice属性用来表示要动用的增高,这样就会代表一个完全的断面了。
我们举多少个例证用尤其认识正则表明式在配备相称方法上的切实选用:
示例1:.*set.*代表全数类中的以set前缀的艺术,如com.baobaotao.Waiter.setSalary(),
Person.setName()等;
示例2:com.advisor.*代表com.advisor包下全体类的富有办法;
示例3:com.service.*Service.* 牢相配com.service包下全数类名以Service结尾的类的有着办法,如com.service.User瑟维斯.save(User user)、com.service.Forum瑟维斯.update(Forum forum)等艺术;
示例4:com.service.*.save.+ 相配com.service包中具有类中所以save为前缀的不二等秘书诀。如相配com.service.UserService类的saveUser()和saveLoginLog()方法,但不宽容该类中的save()方法。

  • AopProxy有五个落到实处类,分别代表jdk动态代理和cglib动态代理
    • org.springframework.aop.framework.JdkDynamicAopProxy
    • org.springframework.aop.framework.CglibAopProxy
  • 代理对象创设时,在DefaultAopProxyFactory.createAopProxy()中判定是成立JdkDynamicAopProxy还代理对象创立是CglibAopProxy,ObjenesisCglibAopProxy是CglibAopProxy的子类
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="beforeAdvice" class="spring4.aop.BeforeAdvice"/>
    <bean id="afterAdvice" class="spring4.aop.AfterAdvice"/>
    <bean id="roundAdvice" class="spring4.aop.RoundAdvice"/>
    <bean id="service" class="spring4.ServiceImpl"/>

    <bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="advice" ref="beforeAdvice"/>
        <!--正则表达式用来表示增加添加到哪些类的哪些方法-->
        <property name="pattern" value="spring4..*.print.*"/><!--表示应用到spring4包下所有类中的所有print开头的方法上-->
    </bean>
    <bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

        <property name="interceptorNames">
            <list>
                <value>advisor</value><!--这里可以是advice,也可以是advisor-->

            </list>
        </property>
        <property name="target" ref="service"></property>
    </bean>

</beans>

在原service加多三个措施便于观看

 public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy; } return new ObjenesisCglibAopProxy; } else { return new JdkDynamicAopProxy; } }
package spring4.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring4.Service;

/**
 * Created by weixin:javajidi_com.
 */
public class Test {

    public static void main(String[] arg){
//        Service service=new ServiceImpl();
//        //使用代理工厂为目标对象创建代理,并织入我们自己的advice逻辑
//        ProxyFactory proxyFactoryBean=new ProxyFactory();
//        proxyFactoryBean.setTarget(service);//设置目标对象
//        proxyFactoryBean.addAdvice(new BeforeAdvice());//为目标对象织入增强
//        proxyFactoryBean.addAdvice(new AfterAdvice());
//        proxyFactoryBean.addAdvice(new RoundAdvice());
//        Service proxy=(Service)proxyFactoryBean.getProxy();
//        proxy.print("test");

        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("classpath:spring.xml");
        Service service=applicationContext.getBean("serviceProxy",Service.class);
        service.print("print");
        service.say("say");
    }
}
  • org.springframework.aop.Advisor,仅包涵三个advice的断面,advice横切全体的Jointpoint
  • org.springframework.aop.PointcutAdvisor,具备切点的切面,包括Pointcut、Advice
    • org.springframework.aop.support.DefaultPointcutAdvisor,富含自由Pointcut、Advice,不协理引导介绍切面
    • org.springframework.aop.support.NameMatchMethodPointcutAdvisor,按章程名定义切点
    • org.springframework.aop.support.RegexpMethodPointcutAdvisor,通过正则定义切点
    • org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor,静态方法定义切点
    • org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor,AspectJ表明式定义切点
    • org.springframework.aop.aspectj.AspectJPointcutAdvisor,AspectJ语法定义切点
  • org.springframework.aop.IntroductionAdvisor,引导介绍切面
  • 应用StaticMethodMatcherPointcutAdvisor定义切面,拦截Watier类的greetTo()

运作结果

BeforeAdvice方法执行前
print;class spring4.ServiceImpl
我是业务方法print
say:say
public class GreetingAdvisor extends StaticMethodMatcherPointcutAdvisor { /** * Pointcut 方法匹配规则 */ @Override public boolean matches(Method method, Class<?> targetClass) { return "greetTo".equals(method.getName; } /** * Pointcut 类匹配规则 */ @Override public ClassFilter getClassFilter() { ClassFilter classFilter = new ClassFilter() { /** * 匹配Watier类或Watier子类 */ @Override public boolean matches(Class<?> clazz) { return Watier.class.isAssignableFrom; } }; return classFilter; }}

可知独有print方法被参预了提升

  • 应用RegexpMethodPointcutAdvisor定义切面,拦截任意类中的greet

在前边的例证中,大家都通过ProxyFactoryBean创立织入切面包车型大巴代办,每二个索要被代理的Bean都亟待利用二个ProxyFactoryBean进行布置。对由具备比相当多亟需代理Bean的种类,那将万分艰巨。

侥幸的是,Spring为大家提供了机关代理体制,让容器为大家自动生成代理,把大家从麻烦的布置职业中解放出来。在里面,Spring使用BeanPostProcessor自动地做到这项工作。那么些依据BeanPostProcessor的机关代理创立器的完成类,将基于一些条条框框自动在容器实例化Bean时为同盟的Bean生成代理实例。这个代理创设器能够分成以下三类:

 <bean p:advice-ref="greetingAdvice"> <property name="patterns"> <list> <value>.*greet.*</value> </list> </property> </bean>

.基于Bean配置名法规的机关代理创造器:允许为一组特定配置名的Bean自动成立代理实例的代理创立器,达成类为BeanNameAutoProxyCreator;

  • 应用ProxyFacotryBean创制代理,各个Bean都亟需一个ProxyFactoryBean,Spring基于BeanPostProcessor机制完结活动代理制造器,简化代理创立进度
  • org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator,依照bean的布置行称成立机关代理创造器

.基于Advisor相配机制的机关代理创建器:它会对容器中有着的Advisor实行围观,自动将那么些切面应用到极其的Bean中(即为目的Bean创造代理实例),完毕类为DefaultAdvisorAutoProxyCreator;

.基于Bean中AspectJ证明标签的电动代理创设器:为蕴涵AspectJ声明的Bean自动成立代理实例,它的落实类是AnnotationAwareAspectjAutoProxyCreator。

 p:interceptorNames="可以配置advice、advisor" 配置advice拦截所有方法,配置advisor可以自定义Pointcut继承PointcutAdvisor实现Pointcut规则 p:interceptorNames="指定一个或多个增强的bean" <bean p:beanNames="seller,watier,*er" p:interceptorNames="greetingAdvisor" p:optimize="true"> </bean>

具有的自发性代理创制器类都完毕了BeanPostProcessor,在容器实例化Bean时,BeanPostProcessor将对它进行加工管理,所以,自动代理创建器有时机对满意相配法则的Bcan自动成立代理对象。
行使时,大家只需在容器中登记相应bean就能够知效。

  • org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator,扫描容器中享有的advisor,自动匹配bean创设机关代理成立器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="beforeAdvice" class="spring4.aop.BeforeAdvice"/>
    <bean id="afterAdvice" class="spring4.aop.AfterAdvice"/>
    <bean id="roundAdvice" class="spring4.aop.RoundAdvice"/>
    <bean id="service" class="spring4.ServiceImpl"/>

    <bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="advice" ref="beforeAdvice"/>
        <!--正则表达式用来表示增加添加到哪些类的哪些方法-->
        <property name="pattern" value="spring4..*.print.*"/><!--表示应用到spring4包下所有类中的所有print开头的方法上-->
    </bean>

    <!--会扫描所有容器中的advisor,然后自动为这些advisor要应用的bean生成代理-->
  <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

</beans>

package spring4.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring4.Service;

/**
 * Created by weixin:javajidi_com.
 */
public class Test {

    public static void main(String[] arg){
//        Service service=new ServiceImpl();
//        //使用代理工厂为目标对象创建代理,并织入我们自己的advice逻辑
//        ProxyFactory proxyFactoryBean=new ProxyFactory();
//        proxyFactoryBean.setTarget(service);//设置目标对象
//        proxyFactoryBean.addAdvice(new BeforeAdvice());//为目标对象织入增强
//        proxyFactoryBean.addAdvice(new AfterAdvice());
//        proxyFactoryBean.addAdvice(new RoundAdvice());
//        Service proxy=(Service)proxyFactoryBean.getProxy();
//        proxy.print("test");

        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("classpath:spring.xml");
        Service service=applicationContext.getBean("service",Service.class);
        service.print("print");
        service.say("say");
    }
}

运作结果一样。

 <bean ></bean> <!-- advisor 根据正则匹配类中的方法--> <bean p:advice-ref="greetingAdvice"> <property name="patterns"> <list> <value>.*greet.*</value> </list> </property> </bean>
  • org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator,为AspectJ注解创设机关代理创制器

本文由365bet体育在线官网发布于网络工程,转载请注明出处:Spring AOP基础

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。