扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
这篇文章主要讲解了“Spring AOP核心类有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Spring AOP核心类有哪些”吧!
潢川网站建设公司创新互联建站,潢川网站设计制作,有大型网站制作公司丰富经验。已为潢川上千多家提供企业网站建设服务。企业网站搭建\外贸网站建设要多少钱,请找那个售后服务好的潢川做网站的公司定做!
我们先来看下AnnotationAwareAspectJAutoProxyCreator类的结构图。
上图中一些 类/接口的介绍:
AspectJAwareAdvisorAutoProxyCreator: 公开了AspectJ的调用上下文,并弄清楚来自同一切面的多个Advisor在AspectJ中的优先级规则。
AbstractAdvisorAutoProxyCreator: 通用自动代理创建器,它基于检测到的每个顾问程序为特定bean构建AOP代理。
AbstractAutoProxyCreator: 扩展了 ProxyProcessorSupport,实现了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 接口,是BeanPostProcessor 实现,该实现使用AOP代理包装每个合格的bean,并在调用bean本身之前委派给指定的拦截器。
BeanFactoryAware: 实现了该接口的Bean可以知道它属于那个 BeanFactory,Bean可以通过Spring容器查找它的协同者(依赖查找),但大多数的Bean是通过构造器参数和Bean方法(依赖注入)来获取它的协同者。
BeanPostProcessor:工厂钩子,允许自定义修改新的bean实例。例如,检查标记接口或使用代理包装bean。如果我们需要在Spring容器中完成Bean的实例化,配置和其初始化前后添加一些自己的逻辑处理,我们就可以定义一个或多个BeanPostProcessor接口的实现,然后注册到容器中。
InstantiationAwareBeanPostProcessor: BeanPostProcessor 的子接口,它添加了实例化之前的回调,以及实例化之后但设置了显式属性或自动装配之前的回调。它内部提供了3个方法,再加上BeanPostProcessor接口内部的2个方法,实现这个接口需要实现5个方法。InstantiationAwareBeanPostProcessor 接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置。
SmartInstantiationAwareBeanPostProcessor: InstantiationAwareBeanPostProcessor 接口的扩展,多出了3个方法,添加了用于预测已处理bean的最终类型的回调,再加上父接口的5个方法,所以实现这个接口需要实现8个方法,主要作用也是在于目标对象的实例化过程中需要处理的事情。
总之:AspectJAwareAdvisorAutoProxyCreator为 AspectJ 切面类创建自动代理。
BeanPostProcessor接口中的两个方法 postProcessBeforeInitialization 和 postProcessAfterInitialization,作用是对Bean初始化前后添加一些自己的逻辑。
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
InstantiationAwareBeanPostProcessor是 BeanPostProcessor的子接口,它额外增加了3个新的方法:postProcessBeforeInstantiation( 目标对象被实例化之前调用的方法,可以返回目标实例的一个代理用来代替目标实例 )、postProcessAfterInstantiation(该方法在Bean实例化之后执行,返回false,会忽略属性值的设置;如果返回true,会按照正常流程设置属性值) 和 postProcessPropertyValues(对属性值进行修改,未来版本将会删除)
@Nullable
default Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
SmartInstantiationAwareBeanPostProcessor接口继承InstantiationAwareBeanPostProcessor接口,里面定义了3个方法:predictBeanType(预测Bean的类型)、determineCandidateConstructors(选择合适的构造器)、getEarlyBeanReference(解决循环引用问题)。
@Nullable
default Class> predictBeanType(Class> beanClass, String beanName) throws BeansException {
return null;
}
@Nullable
default Constructor>[] determineCandidateConstructors(Class> beanClass, String beanName) throws BeansException {
return null;
}
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
AbstractAutoProxyCreator是AOP的一个核心类,它实现了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 接口,实现了代理创建的逻辑,使用AOP代理包装每个合格的bean,并在调用bean本身之前委派给指定的拦截器。
AbstractAdvisorAutoProxyCreator通用自动代理创建器,它基于检测每个bean的增强器,为特殊的bean构建AOP代理。子类可以重写此findCandidateAdvisors()方法,以返回适用于任何对象的advisor的自定义列表,子类还可以重写继承的AbstractAutoProxyCreator.shouldSkip()方法,以将某些对象排除在自动代理之外。
protected List findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
AspectJAwareAdvisorAutoProxyCreator扩展 AbstractAdvisorAutoProxyCreator,公开了AspectJ的调用上下文,并在多个增强器来自同一切面时搞清楚AspectJ的建议优先级顺序。按AspectJ优先级排序其余部分:
@Override
@SuppressWarnings("unchecked")
protected List sortAdvisors(List advisors) {
List partiallyComparableAdvisors = new ArrayList<>(advisors.size());
for (Advisor element : advisors) {
partiallyComparableAdvisors.add(
new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR));
}
List sorted = PartialOrder.sort(partiallyComparableAdvisors);
if (sorted != null) {
List result = new ArrayList<>(advisors.size());
for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
result.add(pcAdvisor.getAdvisor());
}
return result;
}
else {
return super.sortAdvisors(advisors);
}
}
在增强链头部增加一个ExposeInvocationInterceptor,使用AspectJ表达式切入点和使用AspectJ样式的advisor时,需要这些附加advisor。
protected void extendAdvisors(List candidateAdvisors) {
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
}
如果此后处理器不应该考虑将给定的bean用于自动代理,子类应重写此方法以返回true
@Override
protected boolean shouldSkip(Class> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
List candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
AspectJAwareAdvisorAutoProxyCreator还有一个子类叫 AnnotationAwareAspectJAutoProxyCreator,子类AnnotationAwareAspectJAutoProxyCreator是用于处理当前应用程序上下文中的所有AspectJ注释方面以及Spring Advisor。如果Spring AOP的基于代理的模型能够应用任何AspectJ注释的类,它们的advisor将被自动识别,这涵盖了方法执行连接点,Spring Advisor的处理遵循AbstractAdvisorAutoProxyCreator中建立的规则。
从使用aop:xxx标签来自动生成代理的话,先看看AopNamespaceHandler,使用aop:config标签则使用 ConfigBeanDefinitionParser 解析,使用了aop:aspectj-autoproxy标签则使用 AspectJAutoProxyBeanDefinitionParser 解析,依次类推。
@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());
}
ConfigBeanDefinitionParser.java
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
CompositeComponentDefinition compositeDef =
new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compositeDef);
configureAutoProxyCreator(parserContext, element); // 注册AspectJAwareAdvisorAutoProxyCreator
List childElts = DomUtils.getChildElements(element);
for (Element elt: childElts) {
String localName = parserContext.getDelegate().getLocalName(elt);
if (POINTCUT.equals(localName)) {
parsePointcut(elt, parserContext);
}
else if (ADVISOR.equals(localName)) {
parseAdvisor(elt, parserContext);
}
else if (ASPECT.equals(localName)) {
parseAspect(elt, parserContext);
}
}
parserContext.popAndRegisterContainingComponent();
return null;
}
private void configureAutoProxyCreator(ParserContext parserContext, Element element) {
AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);
}
AopConfigUtils.java
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
CompositeComponentDefinition compositeDef =
new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compositeDef);
configureAutoProxyCreator(parserContext, element); // 注册AspectJAwareAdvisorAutoProxyCreator
List childElts = DomUtils.getChildElements(element);
for (Element elt: childElts) {
String localName = parserContext.getDelegate().getLocalName(elt);
if (POINTCUT.equals(localName)) {
parsePointcut(elt, parserContext);
}
else if (ADVISOR.equals(localName)) {
parseAdvisor(elt, parserContext);
}
else if (ASPECT.equals(localName)) {
parseAspect(elt, parserContext);
}
}
parserContext.popAndRegisterContainingComponent();
return null;
}
private void configureAutoProxyCreator(ParserContext parserContext, Element element) {
AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);
}
AopConfigUtils.java
public static void registerAspectJAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
// 在这里注册的是AspectJAwareAdvisorAutoProxyCreator
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext); // 注册组件
}
@Nullable
public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source);
}
AspectJAwareAdvisorAutoProxyCreator实现了 BeanPostProcessor等上面介绍的接口,主要作用于Bean初始化前后,实例化前后,所有的Bean都被作用到。InstantiationAwareBeanPostProcessor是 BeanPostProcessor的子接口,但它的调用时间点发生在Bean实例化前,在真正调用doCreateBean()创建bean实例之前执行postProcessBeforeInstantiation()。
AbstractAutoProxyCreator.java
@Override
public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName); // 得到一个缓存的唯一key(根据beanClass和beanName生成唯一key)
// 如果当前targetSourcedBeans(通过自定义TargetSourceCreator创建的TargetSource)不包含cacheKey
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) { //advisedBeans(已经被增强的Bean,即AOP代理对象)中包含当前cacheKey,返回null,即走Spring默认流程
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {// 如果是基础设施类(如Advisor、Advice、AopInfrastructureBean的实现)不进行处理;(略)
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// 如果有自定义的TargetSource,在此处创建代理
// 禁止目标Bean的不必要的默认实例化:
// TargetSource将以自定义方式处理目标实例。
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;
}
通过 AbstractAutoProxyCreator 中的 postProcessAfterInitialization() 创建AOP代理。
@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)) { // 如果之前调用过getEarlyBeanReference获取包装目标对象到AOP代理对象(如果需要),则不再执行
return wrapIfNecessary(bean, beanName, cacheKey); // 包装目标对象到AOP代理对象(如果需要)
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { // 通过TargetSourceCreator进行自定义TargetSource不需要包装
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { // 不应该被增强对象不需要包装
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { // 基础设施或应该skip的不需要保证
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 如果有advise则创建代理。
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;
}
感谢各位的阅读,以上就是“Spring AOP核心类有哪些”的内容了,经过本文的学习后,相信大家对Spring AOP核心类有哪些这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流