概述:
aop是spring框架的核心思想之一,系統開發中會採用aop的方式進行業務邏輯的動態植入,如登錄授權、日誌統計等。該篇文章首先會講解aop的基礎概念,然後講解spring通過命名空間方式如何實現aop的功能。
- AOP基礎:
AOP核心概念
對比 | 效率 | 共同依賴 | 依賴 | 實現方式 |
Cglib | 較高效 | aopalliance (標準接口包) aspectjweaver |
ASM.jar(java字節碼操縱框架) cglib.jar |
加載目標類的字節碼,植入需要增強處理 然後動態生成目標類的子類 生成的類與目標類屬於繼承關係 |
JDK | 無 | 採用JDK自帶動態代理方式,獲取目標類的 接口,動態生成接口的實現類 生產的類與目標類屬於接口的不同實現類 不能進行強制轉換操作 |
- spring如何實現AOP功能
public class AopNamespaceHandler extends NamespaceHandlerSupport {
/**
* Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the
* '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}'
* and '{@code scoped-proxy}' tags.
*/
@Override
public void init() {
// In 2.0 XSD as well as in 2.1 XSD.
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace as of 2.1
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
}
看下AspectJAutoProxyBeanDefinitionParser類: @Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
extendBeanDefinition(element, parserContext);
return null;
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
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;
}
// 創建一個名稱爲org.springframework.aop.config.internalAutoProxyCreator的bean定義
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;
}
創建好bean定義後設置proxy-target-class、expose-proxy兩個參數值