説明
コードの準備
jar
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
aop
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HodayDouble {
}
@Aspect
@Component
public class OperationAop {
@Pointcut("@annotation(com.hx.anno.HodayDouble)")
public void doCut(){}
@Around("doCut()")
public int doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object[] args = proceedingJoinPoint.getArgs();
int i = (int) args[0];
int j = (int) args[1];
System.out.println("入力: i:" + i);
System.out.println("入力: j:" + j);
System.out.println("before around");
int result = (int) proceedingJoinPoint.proceed();
System.out.println("after around");
System.out.println("生の結果:" + result);
result = result * 2;
System.out.println("プロキシの結果:" + result);
return result;
}
@Before("doCut()")
public void doBefore(){
System.out.println("@Before print");
}
@After("doCut()")
public void doAfter(){
System.out.println("@After print");
}
public void test(){
}
}
プロキシ・クラス
@Component
public class OperationUtil {
@HodayDouble
public int add(int i, int j){
int result = i + j;
return result;
}
}
共通クラス
@Service("service")
public class OperationService {
@Autowired
private OperationUtil ops;
public int add(int i , int j){
return ops.add(i,j);
}
}
ポスト・プロセッサ分析
AbstractApplicationContext->refresh():
// ポストプロセッサを登録する
registerBeanPostProcessors(beanFactory);
AbstractApplicationContext->registerBeanPostProcessors():
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
PostProcessorRegistrationDelegate->registerBeanPostProcessors():
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
それはどこから来るのでしょうか?
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration$CglibAutoProxyConfiguration
遡ると、コンフィギュレーション・クラスのBeanを追加したときに、以下のようにロードされたBeanを見つけました:
ConfigurationClassBeanDefinitionReader->loadBeanDefinitionsForConfigurationClass():
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
ConfigurationClassBeanDefinitionReader->loadBeanDefinitionsFromRegistrars:
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry));
AspectJAutoProxyRegistrar->registerBeanDefinitions():
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AopConfigUtils->registerAspectJAnnotationAutoProxyCreatorIfNecessary():
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
AopConfigUtils->registerAspectJAnnotationAutoProxyCreatorIfNecessary():
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
importBeanDefinitionRegistrars
元々はbdMapとbdNamesに属性として追加されたものです。
なぜ
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration$CglibAutoProxyConfiguration
で紹介されたので、まずクラスを見てみましょう。
AspectJAutoProxyRegistrar
CglibAutoProxyConfiguration
のAopAutoConfiguration
内部クラスであることに注意してください。
importBeanDefinitionRegistrars
ここで@ConditionalOnClassアノテーションを見つけました、そして、プロジェクトが存在する場合、括弧内のクラスだけが解析されることがわかりました、そして、このAdviceクラスは、たまたまaspectjパッケージの下にあります、そして、AopAutoConfigurationによってさえ解析されません、ましてや、その内部クラス、そして、当然のことながら、プロパティのようなものは存在しません。