spring aop(九)--使用DefaultAdvisorAutoProxyCreator创建代理

根据spring-framework-reference,DefaultAdvisorAutoProxyCreator创建代理更加通用强大,使用此机制包括:
a.指定一个DefaultAdvisorAutoProxyCreator Bean的定义.
b.指定在相同或相关的上下文中任意数量的Advisor.注意,必须是Advisor,而不仅仅是interceptor或advice.这是必要的,因为必须有一个切点被评估,以便检查每个advice到候选bean定义是否合格.
下面举个应用例子.

1.主要依赖(略)

2.具体类.

@Configuration
public class AppConfig {
	//要创建代理的目标Bean
	@Bean
	public UserService userService(){
		return new UserServiceImpl();
	}
	//创建Advice
	@Bean
	public Advice myMethodInterceptor(){
		return new MyMethodInterceptor();
	}
	//使用Advice创建Advisor
	@Bean
	public NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor(){
		NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor=new NameMatchMethodPointcutAdvisor();
		nameMatchMethodPointcutAdvisor.setMappedName("pri*");
		nameMatchMethodPointcutAdvisor.setAdvice(myMethodInterceptor());
		return nameMatchMethodPointcutAdvisor;
	}
	@Bean
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
		return new DefaultAdvisorAutoProxyCreator();
	}
}

public interface UserService {
	void print();
}
public class UserServiceImpl implements UserService {
	public void print(){
		System.out.println(getClass()+"#print");
	}
}
public class MyMethodInterceptor implements MethodInterceptor {
	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		System.out.println(getClass()+"调用方法前");
		Object ret=invocation.proceed();
		System.out.println(getClass()+"调用方法后");
		return ret;
	}
}

3.测试

public class Main {
	public static void main(String[] args) {
		ApplicationContext applicationContext=new AnnotationConfigApplicationContext(AppConfig.class);
		UserService userService= applicationContext.getBean(UserService.class);
		userService.print();
	}
}
跟踪下实现:
和BeanNameAutoProxyCreator一样,DefaultAdvisorAutoProxyCreator也是一个BeanPostProcessor.它在Bean实例化随后,调用回调org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization进行后期处理来完成代理的创建.
其中AbstractAutoProxyCreator是BeanNameAutoProxyCreator的超类,BeanNameAutoProxyCreator没有重写postProcessAfterInitialization方法.下面看看这个方法:
看看wrapIfNecessary方法:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	//这个bean是否匹配要创建代理也是在这个方法.
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	if (specificInterceptors != DO_NOT_PROXY) {
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
		//关键代码在这里
		Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
		this.proxyTypes.put(cacheKey, proxy.getClass());
		return proxy;
	}

	this.advisedBeans.put(cacheKey, Boolean.FALSE);
	return bean;
}

先看看org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean方法(与BeanNameAutoProxyCreator不同),此处就可以找到在AppConfig配置的NameMatchMethodPointcutAdvisor.

@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
	if (advisors.isEmpty()) {
		return DO_NOT_PROXY;
	}
	return advisors.toArray();
}
剩下的就与BeanNameAutoProxyCreator创建代理类似了.

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值