Spring 5.x Source trip forty-three AnnotationAwareAspectJAutoProxyCreator
What is AnnotationAwareAspectJAutoProxyCreator
Then on a long time did not look at this chart, and looks like a very complicated, in fact, there are ways to achieve sub-class, and he just inherited, you can be understood as a can in bean
many times do things like life cycle.
AOP simple example
Today we find out the AOP
realization of the principle, first of all have to have an example, simply get hold of.
MyLogAspects defining aspects
Which defines a cut point, all methods of all classes in a package and sub-packages, add a Before
comment method, make a log of it. In fact, defined below MyService
class show
way to do enhanced.
@Aspect
@Component
public class MyLogAspects {
/**
* 修饰符 返回类型(一定要有) 包名.类名.方法名(一定要有) 参数
*/
@Pointcut("execution(* com.ww.component.*.*(..))")
public void pointCut() {
}
/**
* 在目标方法执行后
*/
@Before("pointCut()")
public void logBefore() {
System.out.println("logBefore");
}
MyConfig configuration class
Add EnableAspectJAutoProxy
annotations, open AOP
, specifically how to open, and my last article talked about.
@Configuration
@EnableAspectJAutoProxy
public class MyConfig {
@Bean
public IService getService() {
return new MyService();
}
@Bean
public MyLogAspects getMyLogAspects() {
return new MyLogAspects();
}
}
MyService define an interface and implementation class
We want to show
do enhancement methods.
@Service
public class MyService implements IService {
@Override
public void show() {
System.out.println("MyService show");
}
}
public interface IService {
void show();
}
Test code
@Test
public void AopTest() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(MyConfig.class);
applicationContext.refresh();
IService bean = applicationContext.getBean(IService.class);
bean.show();
}
Result:
We completed the most simple AOP
, let's look at how he did it.
How is the realization of AOP
Let us not look at the source code, Imagine, we should first resolve our own MyLogAspects
section, and then know what kind of method which needs to be enhanced, then found that when a certain class of processor, then the agent, in the method of the method can be added in front of a print information, the logic should be such that substantially specifically we look.
When MyLogAspects analytical section
Earlier we had talked about before with a processor handle instantiation, which is the applyBeanPostProcessorsBeforeInstantiation
method, because we AnnotationAwareAspectJAutoProxyCreator
have implemented this method, this method can be used to cut class to parse it out:
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {//查缓存,是否有处理过了,不管是不是需要通知增强的,只要处理过了就会放里面
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);//要跳过的直接设置FALSE
return null;
}
}
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
isInfrastructureClass whether the internal base class
@Override
protected boolean isInfrastructureClass(Class<?> beanClass) {
return (super.isInfrastructureClass(beanClass) ||
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}
AbstractAutoProxyCreator的isInfrastructureClass
Mainly to see bean
the type is not the type of internal, such as Advice,Pointcut,Advisor,AopInfrastructureBean
these are now AOP
related, so it should not be processed.
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
Whether there is Aspect comment AbstractAspectJAdvisorFactory of isAspect
Mainly to see if there are Aspect
notes, there is no ajc$
beginning of the property name.
@Override
public boolean isAspect(Class<?> clazz) {
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
}
AspectJAwareAdvisorAutoProxyCreator of shouldSkip this is the key
This method is to find Aspect
methods and analytical section of the notifier, notifier Advisor
there are notification Advice
instance.
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
The inside is very complex, next to explain it.
Well, here today, we hope to help study and understand, do not spray the Great God see, understand only their own learning, limited capacity, please excuse.