AOP在Spring中实现,自动归入IOC容器的管理,利用注解和动态代理技术,实现切面功能。spring
@Configuration
//条件配置类,知足条件,就开启AOP功能
@ConditionalOnClass({EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class})
@ConditionalOnProperty(
prefix = "spring.aop",
name = {"auto"},
havingValue = "true",
matchIfMissing = true
)
public class AopAutoConfiguration {
public AopAutoConfiguration() {
}
@Configuration
@EnableAspectJAutoProxy(
proxyTargetClass = true
)
@ConditionalOnProperty(
prefix = "spring.aop",
name = {"proxy-target-class"},
havingValue = "true",
matchIfMissing = true
)
public static class CglibAutoProxyConfiguration {
public CglibAutoProxyConfiguration() {
}
}
@Configuration
@EnableAspectJAutoProxy(
proxyTargetClass = false
)
@ConditionalOnProperty(
prefix = "spring.aop",
name = {"proxy-target-class"},
havingValue = "false",
matchIfMissing = false
)
public static class JdkDynamicAutoProxyConfiguration {
public JdkDynamicAutoProxyConfiguration() {
}
}
}
复制代码
AopAutoConfiguration是SpringBoot为AOP提供的自动装配类。缓存
SpringBoot自动开启Aop代理机制,默认CglibAutoProxyConfiguration配置。若是须要基于接口的动态代理(JDK基于接口的动态代理) , 须要设置spring.aop.proxy-target-class属性为false。框架
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
/**
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
* to standard Java interface-based proxies. The default is {@code false}.
*/
boolean proxyTargetClass() default false;
/**
* Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
* for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
* Off by default, i.e. no guarantees that {@code AopContext} access will work.
* @since 4.3.1
*/
boolean exposeProxy() default false;
}
复制代码
注解开启代理机制,告诉Spring容器,支持注解式Aspect。ide
proxyTargetClass 指定是否使用CGLIB的方式建立实现接口的目标对象的代理。缺省值为false,使用JDK方式建立接口对象的代理。源码分析
exposeProxy标记代理对象是否应该被aop框架经过AopContext以ThreadLocal的形式暴露出去。当一个代理对象须要调用它本身的另一个代理方法时,这个属性将很是有用。默认是是false,以免没必要要的拦截。post
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
复制代码
这个类注册AspectJAnnotationAutoProxyCreator,而且enableAspectJAutoProxy获取EnableAspectJAutoProxy的注解信息,默认强制开启类代理。ui
public abstract class AopConfigUtils {
.....
@Nullable
public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAutoProxyCreatorIfNecessary(registry, (Object)null);
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
} else {
// 注册AnnotationAwareAspectJAutoProxyCreator
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", -2147483648);
beanDefinition.setRole(2);
registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
return beanDefinition;
}
}
}
复制代码
开始的时候AutoProxyCreator类不存在,RootBeanDefinition初始化AnnotationAwareAspectJAutoProxyCreator类,注册类到IOC容器。this
继承关系lua
AnnotationAwareAspectJAutoProxyCreator->AspectJAwareAdvisorAutoProxyCreator->AbstractAdvisorAutoProxyCreator->AbstractAutoProxyCreatorspa
Bean生命周期的后置处理
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware{
......
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
//获取要织入到beanName目标对象的切入点的全部通知
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
....
}
复制代码
重点:建立代理类
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 (this.shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
this.evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
this.customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (this.advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(this.getProxyClassLoader());
}
复制代码
继承关系
DefaultAopProxyFactory->AopProxyFactory
建立代理工厂
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
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.");
} else {
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
}
复制代码
class接口走JDK代理,类走Cglib代理。
继承关系
JdkDynamicAopProxy->AopProxy
ObjenesisCglibAopProxy->CglibAopProxy->AopProxy
得到代理对象
public interface AopProxy {
Object getProxy();
Object getProxy(@Nullable ClassLoader var1);
}
public Object getProxy() {
return this.getProxy(ClassUtils.getDefaultClassLoader());
}
复制代码
1.AopAutoConfiguration实现Aop的自动装配,配置好依赖就能直接使用。
2.EnableAspectJAutoProxy注解,开启AspectJ的代理功能。
3.AspectJAutoProxyRegistrar实现动态注册AnnotationAwareAspectJAutoProxyCreator,归入IOC容器管理。
4.AnnotationAwareAspectJAutoProxyCreator实现生命周期监听,后置处理AspectJ切入的类,查找缓存全部的Advisors,建立代理类对象。
5.DefaultAopProxyFactory提供代理策略,接口走JDK代理,类走Cglib代理。SpringBoot默认走Cglib代理。
6.AopProxy建立代理类,代理类里面会插入Advisor注解的方法中的代码,并返回代理对象。