aop自定义配置
aop利用了spring的自定义标签
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
在bean的配置文件中只要找到了aop命名空间对应的标签,就会通过AopNamespaceHandler进行解析。
@Override
public void init() {
// In 2.0 XSD as well as in 2.5+ XSDs
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace in 2.5+
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
aop注册beanPostProcessor
重点来分析一下AspectJAutoProxyBeanDefinitionParser
public BeanDefinition parse(Element element, ParserContext parserContext) {
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
extendBeanDefinition(element, parserContext);
return null;
}
// 主要是注册了这个AnnotationAwareAspectJAutoProxyCreator bean定义
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
AnnotationAwareAspectJAutoProxyCreator这个类实现了InstantiationAwareBeanPostProcessor这个接口。按照前文描述的扩展点来说会在bean的实例化周期按照次序调用其具体的方法。主要关注一下postProcessAfterInitialization。 aop就是利用了这个方法,在获取到原对象之后对其进行增强。
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
简短总结:
aop生效的原理
配置了aop,就会让其注册AnnotationAwareAspectJAutoProxyCreator这个bean定义,其本质利用了spring的扩展点,让每一个bean初始化之后都会调用postProcessAfterInitialization方法,从而返回生成的新的代理对象
aop的postProcess方法
在上述描述中已经知道为什么aop会生效了,其postProcessAfterInitialization方法也就是生成代理的方法,其实生成代理的方法也很好描述,就是找到哪个对象需要代理,代理之后的方法如何实现。
aop中三个概念
Advice
Advice 就是你想要添加到现有代码中的额外逻辑。
Pointcut
决定了“哪里”应用 Advice
Advisor
可以看作是一个将 Advice 与 Pointcut 结合起来的概念
找到advisor
// 找到合适的advisor的外层方法
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 找到所有的advisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 找到当前bean对应的advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
// 找到所有的advisor
protected List<Advisor> findCandidateAdvisors() {
// 找到实现了advisor接口的对象
List<Advisor> advisors = super.findCandidateAdvisors();
// 找到所有被aspect标记的对象
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
// 找到注册到bean工厂定义的所有Advisor
public List<Advisor> findAdvisorBeans() {
String[] advisorNames = this.cachedAdvisorBeanNames;
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
for (String name : advisorNames) {
List<Advisor> advisors = new ArrayList<Advisor>();
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
}
// 这个是pointcutAdvisor类型的根据当前类匹配advisor的方法
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if ((introductionAwareMethodMatcher != null &&
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
代理增强
代理增强有两种方案
一种是基于接口的jdk动态代理、而是基于当前类为父类的cglib动态代理。默认是jdk动态代理,但是如果在aop配置中指定了traget-class,则会默认使用cglib
入口:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy
// 生成动态代理工厂,然后去获取代理类
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
return proxyFactory.getProxy(getProxyClassLoader());
}
接下来以jdk动态代理为例,看看其是怎么生成代理的,jdk动态代理主要是要实现InvocationHandler接口,然后在调用方法的时候会调用到其invoke方法
public Object getProxy(ClassLoader classLoader) {
// 找到合适的代理的父接口,然后生成代理
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 构建切面的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 通过构造的拦截器链进行方法调用
retVal = invocation.proceed();
}
通过切面构造拦截器链的过程。主要两种方式
1、通过注册到AdvisorAdapterRegistry
2、advisor本身实现了MethodInterceptor接口
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
public MethodInterceptor[] getInterceptors(Advisor advisor) {
List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
Advice advice = advisor.getAdvice();
// 自身实现了MethodInterceptor接口
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
// 通过注册上来的适配器,转换成对应的interceptor
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
// 默认注册上来的interceptor
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
链式调用interceptor方法
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
public Object proceed() throws Throwable {
// 调用链执行完了之后,执行被代理对象的方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获取下一个执行的拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 执行下一个拦截器的invoke方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}