描述:在Spring框架中,AOP模块是通过实现BeanPostProcessor相关类型与IOC模块集成的
UML结构图如下:
AbstractAdvisingBeanPostProcessor:BeanPostProcessor的基本实现,将一个Spring AOP advisor应用到多个spring bean
属性:
@Nullable
protected Advisor advisor;
protected boolean beforeExistingAdvisors = false;
private final Map<Class<?>, Boolean> eligibleBeans = new ConcurrentHashMap<>(256);
核心方法:
1.postProcessBeforeInitialization
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
2.postProcessAfterInitialization
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof AopInfrastructureBean || this.advisor == null) {
// Ignore AOP infrastructure such as scoped proxies.
return bean;
}
if (bean instanceof Advised) {
Advised advised = (Advised) bean;
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
// Add our local Advisor to the existing proxy's Advisor chain...
if (this.beforeExistingAdvisors) {
advised.addAdvisor(0, this.advisor);
}
else {
advised.addAdvisor(this.advisor);
}
return bean;
}
}
if (isEligible(bean, beanName)) {
ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
if (!proxyFactory.isProxyTargetClass()) {
evaluateProxyInterfaces(bean.getClass(), proxyFactory);
}
proxyFactory.addAdvisor(this.advisor);
customizeProxyFactory(proxyFactory);
return proxyFactory.getProxy(getProxyClassLoader());
}
// No async proxy needed.
return bean;
}
备注:
-
如果bean已经是Aop Proxy(advised)并且advisor能够应用到bean,将advisor添加到bean的advisor列表中
-
如果advisor能够应用到bean,根据当前配置初始化ProxyFactory,通过proxyFactory.getProxy创建Aop Proxy
辅助方法:
/**
* Check whether the given class is eligible for advising with this
* post-processor's {@link Advisor}.
* <p>Implements caching of {@code canApply} results per bean target class.
* @param targetClass the class to check against
* @see AopUtils#canApply(Advisor, Class)
*/
protected boolean isEligible(Class<?> targetClass) {
Boolean eligible = this.eligibleBeans.get(targetClass);
if (eligible != null) {
return eligible;
}
if (this.advisor == null) {
return false;
}
eligible = AopUtils.canApply(this.advisor, targetClass);
this.eligibleBeans.put(targetClass, eligible);
return eligible;
}
/**
* Prepare a {@link ProxyFactory} for the given bean.
* <p>Subclasses may customize the handling of the target instance and in
* particular the exposure of the target class. The default introspection
* of interfaces for non-target-class proxies and the configured advisor
* will be applied afterwards; {@link #customizeProxyFactory} allows for
* late customizations of those parts right before proxy creation.
* @param bean the bean instance to create a proxy for
* @param beanName the corresponding bean name
* @return the ProxyFactory, initialized with this processor's
* {@link ProxyConfig} settings and the specified bean
* @since 4.2.3
* @see #customizeProxyFactory
*/
protected ProxyFactory prepareProxyFactory(Object bean, String beanName) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
proxyFactory.setTarget(bean);
return proxyFactory;
}
AbstractAutoProxyCreator:BeanPostProcessor实现类,使用AOPProxy(添加对应的拦截器列表)包装符合条件的bean
AbstractAutoProxyCreator区分了不同的拦截器种类。“公共”拦截器:被它创建的所有代理共享; “特定”拦截器:每个bean instance使用独立的拦截器(interceptorNames属性区分)
子类可以应用任何策略来决定是否要对bean进行代理,例如通过类型、名称、定义细节等。它们还可以返回只应用于特定bean实例的额外拦截器。使用TargetSource包装目标bean
UML结构图如下:
备注:getAdvicesAndAdvisorsForBean是抽象方法
核心方法:
1.postProcessBeforeInstantiation
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;
}
备注:通过实现Spring IOC模块的InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法,在Spring Bean对象初始化之前拦截生成Proxy。将AOP模块集成进IOC模块
2.createProxy
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());
}
备注:proxyFactory.copyFrom(this) proxyFactory通过复制AbstractAutoProxyCreator的配置进行初始化,方便通过xml进行配置
流程图如下:
AbstractAdvisorAutoProxyCreator:通用Proxy代理类,根据在Bean上监测到(使用beanfactory)的Advisors建立AOP Proxy
核心方法:
1.getAdvicesAndAdvisorsForBean(从AbstractAutoProxyCreator继承)
AdvisorAdapterRegistry:Spring AOP的内部使用接口,用来登记Advisor适配器。DefaultAdvisorAdapterRegistry具体实现登记Advisor适配器
UML结构图如下:
BeanNameAutoProxyCreator:通过名称列表(beanNames)筛选将bean标识为代理对象(proxy)
核心方法:
1.getAdvicesAndAdvisorsForBean 如果bean名称在配置的名称列表中,则将bean标示为代理(proxy)
DefaultAdvisorAutoProxyCreator:基本与AbstractAdvisorAutoProxyCreator一致,重写了isEligibleAdvisorBean方法
protected boolean isEligibleAdvisorBean(String beanName) {
if (!isUsePrefix()) {
return true;
}
String prefix = getAdvisorBeanNamePrefix();
return (prefix != null && beanName.startsWith(prefix));
}
ProxyConfig:代理的基本配置的父类
UML结构图如下:
ProxyProcessorSupport:提供代理处理器通用功能的基类
UML类图结构如下:
核心方法:
1.evaluateProxyInterfaces
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
boolean hasReasonableProxyInterface = false;
for (Class<?> ifc : targetInterfaces) {
if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
ifc.getMethods().length > 0) {
hasReasonableProxyInterface = true;
break;
}
}
if (hasReasonableProxyInterface) {
// Must allow for introductions; can't just set interfaces to the target's interfaces only.
for (Class<?> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
}
else {
proxyFactory.setProxyTargetClass(true);
}
}
备注:获取BeanClass类型所有接口并根据一定的规则进行筛选;
a. 如果还有可用的接口,添加可用的接口到proxyFactory (JDK Dynamic Proxy)
b.如果没有,设置proxyFactory的ProxyTargetClass属性为true (CGLIb Proxy