前言:
Spring作为java开发必用的开源框架之一,必然有它非常优秀的且不可替代的地方,其中springIOC和Aop就是设计的非常优秀的地方,今天一起来学习一下spring是如何实现AOP
AOP实现的思想:简单来讲就是使用了动态代理,对业务方法进行拦截增强(cglib或者jdk)
继续深入的思考一下如下问题:
- 如何创建动态代理
- 如何判断哪些类需要被代理增强,那些类不需要被增强
- 如何获取通知类
- ……
需要掌握的一些概念或技能:
- 动态代理
- 后置处理器
- Spring的注解的使用如@Import等
- 切面,通知、切点等aop相关的概念
- ……
下面开始跟大家一起学习SpringAOP
一、编写用于debug的aop的demo应用程序
1、业务类Calculator.java
代码语言:javascript复制@Component
public class Calculator {
public int div(int x,int y){
System.out.println("calculator div running...");
return x/y;
}
}
2、切面类LogAspects.java
代码语言:javascript复制@Aspect
@Component
public class LogAspects {
@Pointcut("execution(public int cap1.Calculator.*(..))")
public void pointCut(){}
@Before(value = "pointCut()")
public void logStart(JoinPoint joinPoint){
System.out.println("start...");
System.out.println(joinPoint.getSignature().getName());
for(Object obj : joinPoint.getArgs()){
System.out.println("----" obj);
}
System.out.println(joinPoint.getTarget().toString());
}
@After(value = "pointCut()")
public void logEnd(){
System.out.println("end....");
}
@AfterReturning(value = "pointCut()",returning = "result")
public void logReturn(Object result){
System.out.println("return....");
System.out.println("result = " result);
}
@AfterThrowing(value = "pointCut()",throwing = "exception")
public void logThrowing(Exception exception){
System.out.println("throwing");
}
@Around(value = "pointCut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("around proceeding start....");
Object proceed = joinPoint.proceed();
System.out.println("around proceeding end");
return proceed;
}
}
3、配置类MainConfig.java
代码语言:javascript复制@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class MainConfig1 {
@Bean
public Person person(){
return new Person();
}
}
4、测试类Main1Test.java
代码语言:javascript复制public class Main1Test {
@Test
public void test(){
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig1.class);
for (String name : app.getBeanDefinitionNames()){
System.out.println(name);
}
app.getBean(Calculator.class).div(4,2);
}
}
上面简单的程序就可以模拟springaop啦,下面开始分析springaop工作的原理
在分析之前先说一下springaop的核心的一个类:
BeanName:org.springframework.aop.config.internalAutoProxyCreator
Class:AnnotationAwareAspectJAutoProxyCreator
二、源码分析
1、准备工作—准备向springIOC容器中注入AnnotationAwareAspectJAutoProxyCreator
(1)从EnableAspectJAutoProxy开关开始
(2)@Import注解的使用
(3)AspectJAutoProxyRegistrar#registerBeanDefinitions()
代码语言:javascript复制@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
......
}
(4)AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary()
代码语言:javascript复制@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
(5)AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary()
代码语言:javascript复制@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,
@Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
(6)AopConfigUtils#registerOrEscalateApcAsRequired()
代码语言:javascript复制@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry,
@Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
上面的所有工作都是为了准备向IOC容器中注入AnnotationAwareAspectJAutoProxyCreator
2、向IOC容器中注入各种bean,包括后置处理器(beanpostProcessor)和业务bean,配置bean等所有的bean,这里注意下,向IOC容器中注入bean的时候是先注入后置处理器,然后再注入普通bean,其中后置处理器也是有注入的先后顺序。后置处理器的作用就是用于拦截bean的构建,可以在bean初始化的时候做一些拦截的动作。
下面开始分析代码
(1)AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()
代码语言:javascript复制public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
(2)AbstractApplicationContext#refresh()
代码语言:javascript复制@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
(3)AbstractApplicationContext#registerBeanPostProcessors()先注入后置处理器
注入后置处理器和注入普通的bean的主要的流程差不多,就是时机比注入普通的bean的时机早,因为后置处理器注入成功后,所有的bean都需要经过已经注入的后置处理器进行拦截,同时后置处理器也分先后顺序,实现PriorityOrdered优先注入,其次实现Ordered,最后什么都没有实现的,这是因为实现PriorityOrdered的后置处理器优先级比较高,这种后置处理器可能需要拦截实现Ordered的后置处理器、什么都没实现的后置处理器,以及普通的bean,简单来说就是实例化任何bean都需要被已经实例化出来的后置处理器进行前后拦截。
等下会拿出和AOP相关的两个后置处理器出来分别介绍,他们分别是AnnotationAwareAspectJAutoProxyCreator和EventListenerMethodProcessor前者实现了Orderd接口,后者什么都没实现,所以再实例化EventListenerMethodProcessor时会被AnnotationAwareAspectJAutoProxyCreator进行拦截
PostProcessorRegistrationDelefate#registerBeanPostProcessors()
代码语言:javascript复制public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() 1 postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
(4)AbstractBeanFactory#getBean()
代码语言:javascript复制@Override
public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
(5)AbstractBeanFactory#doGetBean()
代码语言:javascript复制protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//......
//前面是一些校验、检查、标记、依赖注入等操作
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
//......
}
(6)AbstractAutowireCapableBeanFactory#createBean()
代码语言:javascript复制@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" beanName "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" beanName "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
这里有一个需要注意的地方:Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
这一行代码比较容易忽略,这里面就有后置处理器的拦截工作,但是当注入AnnotationAwareAspectJAutoProxyCreator时,基本上拦截的后置处理器不做任何事情,感兴趣的可以debug看一下,但是当AnnotationAwareAspectJAutoProxyCreator已经初始化好的话,注入在AnnotationAwareAspectJAutoProxyCreator后的bean会被AnnotationAwareAspectJAutoProxyCreator拦截(前置拦截),这里介绍一下EventListenerMethodProcessor,为什么要介绍它,因为该后置处理器会实例化所有的通知类Adviser。仔细看一下…
(7)AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation()
代码语言:javascript复制@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
重点看 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName)前置处理,其实就是遍历所有已经实例化好的后置处理器进行拦截,除了AnnotationAwareAspectJAutoProxyCreator,其他的一般不做任何处理,debug可以详细查看
(8)AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation()
代码语言:javascript复制protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
(9)AbstractAutoProxyCreator#postProcessBeforeInstantiation()
这里是看被AnnotationAwareAspectJAutoProxyCreator拦截处理的逻辑
代码语言:javascript复制public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
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);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
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;
}
这里比较重要:
①会先将后面的每个bean进行标记,this.advisedBeans.put(cacheKey, Boolean.FALSE);在后面后置处理的时候如果是false就直接返回,不进行代理。
②会实例化Advisor,逻辑在shouldSkip中,看一下
(10)AspectJAutowareAdvisorAutoProxyCreator#shouldSkip()
代码语言:javascript复制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);
}
(11)AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()
代码语言:javascript复制@Override
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
(12)BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors()
代码语言:javascript复制public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new LinkedList<>();
aspectNames = new LinkedList<>();
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" beanName
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new LinkedList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
这里就是实例化Advisor的详细的逻辑了,看上去很多,但是逻辑也比较简单,意思就是拿到所有的bean的定义信息,然后遍历,判断类型是否是切面类(也就是我们使用了@Aspect注释的类),然后再拿到里面所有的方法进行解析(@Before、@After、@AfterReturning、@AfterThrowing、@Around),后面就不再继续了,这个时候Advisor已经全部放到集合中了。到这里Object bean = resolveBeforeInstantiation(beanName, mbdToUse);就解析完了,我们接着AbstractAutowireCapableBeanFactory#createBean后面的逻辑讲,看到Object beanInstance = doCreateBean(beanName, mbdToUse, args);
(13)AbstractAutowireCapableBeanFactory#doCreateBean
代码语言:javascript复制protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
//.......
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
//......
return exposedObject;
}
重点看初始化bean,初始化就是给bean进行初始化,同样在初始化前后进行拦截增强
(14)AbstractAutowireCapableBeanFactory#initializeBean()
代码语言:javascript复制protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
invokerInitMethods()这是初始化的方法给bean属性赋值
applyBeanPostProcessorsBeforeInitialization()初始化之前进行拦截增强
applyBeanPostProcessorsAfterInitialization()初始化之后进行拦截
为了节省篇幅,这里就直接介绍相应的业务类的初始化拦截了(Calulator),其实所有的bean的初始化的逻辑流程都是一样的,只是部分细节不一样比如上面分析EventListenerMethodProcessor的时候做了初始化Advisor的工作,后面的操作和普通的bean没什么区别,现在主要介绍差异的部分,当初始化Calculator的时候,这个时候会调用
AnnotationAwareAspectJAutoProxyCreator后置处理器进行增强,生成一个Calculator的动态代理类,这是AOP的核心,一起看看如何生成的
(15)AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization()
代码语言:javascript复制@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
这里也会被所有的已经实例化的后置处理器进行拦截,我们重点看AnnotationAwareAspectJAutoProxyCreator,这个时候被拦截的类是Calculator
(16)AbstractAutoProxyCreator#postProcessAfterInitialization()
代码语言:javascript复制@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
wrapIfNecessary()所有被AnnotationAwareAspectJAutoProxyCreator拦截的类都会调用该方法,如果需要对bean进行增强的话,会在这里增强,如果不需要增强的话,会直接返回,看详细逻辑
(17)AbstractAutoProxyCreator#wrapIfNecessay()
代码语言:javascript复制protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && 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;
}
// Create proxy if we have advice.
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;
}
前面两个部分,在第一次前置处理器的时候已经标记过了,所以不符合需要代理的逻辑,直接return了,而calculator走后面的逻辑,create proxy if we hava advice,如果有advisor则进行代理增强,如果没有,则不进行代理增强,前面分析显然是由advisor,所以就会走createProxy的逻辑
(18)AbstractAutoProxyCreator#createProxy()
代码语言:javascript复制protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable 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);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
(19)ProxyFactory#getProxy()
代码语言:javascript复制public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
(20)DefaultAopProxyFactory#createAopProxy()
代码语言:javascript复制public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
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(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
到这里基本就结束了,会通过cglib或者jdk生成calculator的动态代理,这个时候calculator的div方法就进行了增强了
AOP介绍暂时分享到这里,如有错误欢迎指正,后面有时间再跟大家一起学习,调用calculator的div方法如何调用动态代理的方法,以及拦截连的调用和顺序等
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/111221.html原文链接:https://javaforall.cn