一、介绍
Spring 提供了自动代理机制,可以让容器自动生成代理,从而把开发人员从繁琐的配置中解脱出来 。 具体是使用 BeanPostProcessor 来实现这项功能。
二、BeanPostProcessor
BeanPostProcessor有三种实现类分别是:BeanNameAutoProxyCreator、DefaultAdvisorAutoProxyCreator、AnnotationAwareAspectJAutoProxyCreator。
实现类 | 功能 |
---|---|
BeanNameAutoProxyCreator | 基于Bean配置名规则的自动代理创建器,允许为一组特定配置名的Bean自动创建代理实例的代理创建器 |
DefaultAdvisorAutoProxyCreator | 基于Advisor匹配机制的自动代理创建器,它会对容器中所有的Advisor进行扫描,自动将这些切面应用到匹配的Bean中(即为目标Bean创建代理实例) |
AnnotationAwareAspectJAutoProxyCreator | 基于Bean中AspjectJ注解标签的自动代理创建器,为包含AspectJ注解的Bean自动创建代理实例 |
三、BeanNameAutoProxyCreator
target:代理的目标类
beanNames:需要代理的bean的列表
interceptorNames:需要应用到目标对象上的通知Bean的名字.可以是拦截器,advisor和其他通知类型的名字
optimize 设置为 true,则表示使用 CGLib 动态代理技术。
xml配置
<bean
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"
p:beanNames="controller"
p:interceptorNames="exceptionInterceptor"
p:optimize="true"
></bean>
也可以通过 beanNames 的 value 值来明确指定需要代理的 Bean 名称,多个以逗号分隔
<bean id="mcRestServiceProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="controller,test">
</property>
<property name="interceptorNames">
<list>
<!-- 在list配置下面的,会在最里层执行 -->
<value>exceptionInterceptor</value>
</list>
</property>
</bean>
也可以用list方式指定beanNames的值
<bean id="mcRestServiceProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>controller</value>
</list>
</property>
<property name="interceptorNames">
<list>
<!-- 在list配置下面的,会在最里层执行 -->
<value>exceptionInterceptor</value>
</list>
</property>
</bean>
四、DefaultAdvisorAutoProxyCreator
切面 Advisor 是切点和增强的复合体,而 DefaultAdvisorAutoProxyCreator 能够扫描 Advisor, 并将 Advisor 自动织入到匹配的目标 Bean 中。
xml配置
<!--定义一个切面Advisor-->
<bean id="regexpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
p:pattern=".*greet.*"
p:advice-ref="greetingAdvice"/>
<!--该bean负责将容器中的Advisor织入匹配的目标bean中-->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
五、AnnotationAwareAspectJAutoProxyCreator
基于Bean中AspjectJ注解标签的自动代理创建器。
创建用于拦截的 bean
public class TestAopBean {
private String testStr = "testStr";
public void testAop() {
// 被拦截的方法,简单打印
System.out.println(" aop bean");
}
}
创建 Advisor
@Aspect
public class AspectJTest {
@Pointcut("execution(* *.testAop(..))")
public void test() {
}
@Before("test()")
public void beforeTest() {
System.out.println("before Test");
}
@After("test()")
public void afterTest() {
System.out.println("after Test");
}
@Around("test()")
public Object aroundTest(ProceedingJoinPoint joinPoint) {
System.out.println("around Before");
Object o = null;
try {
// 调用切面的方法
o = joinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("around After");
return o;
}
}
首先类打上了 @Aspect 注解,让 Spring 认识到这个是一个切面 bean,在方法打上 @Pointcut(“execution(* *.testAop(…))”),表示这是一个切点方法,execution() 内部的表达式指明被拦截的方法,Before 、After、Around 分别表示在被拦截方法的前、后已经环绕执行。
xml配置
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启 AOP 功能-->
<aop:aspectj-autoproxy />
<bean id="aopTestBean" class="aop.TestAopBean"/>
<bean class="aop.AspectJTest" />
</beans>