在Spring中AOP有几种配置方式,根据我对spring源码的浏览,发现几种实现方式原理如下:
1. ProxyFactoryBean
<bean name="myController" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<list>
<value>pointcut.advisor2</value>
<value>pointcut.advisor1</value>
<value>myRawController</value>
</list>
</property>
</bean>
这个属于最费力不讨好类型的,配置起来很麻烦。原理是根据spring的获取bean的方式,继承了FactoryBean接口的bean在取bean的时候会调用对应的bean class的getObject方法。下面是ProxyFactoryBean的getObject方法:
public Object getObject()
throws BeansException
{
initializeAdvisorChain();
if(isSingleton())
return getSingletonInstance();
if(targetName == null)
logger.warn("Using non-singleton proxies with singleton targets is often undesirable. Enable prototype proxies by setting the 'targetName' property.");
return newPrototypeInstance();
}
private synchronized Object newPrototypeInstance()
{
if(logger.isTraceEnabled())
logger.trace((new StringBuilder("Creating copy of prototype ProxyFactoryBean config: ")).append(this).toString());
ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());
TargetSource targetSource = freshTargetSource();
copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain());
if(autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass())
copy.setInterfaces(ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), proxyClassLoader));
copy.setFrozen(freezeProxy);
if(logger.isTraceEnabled())
logger.trace((new StringBuilder("Using ProxyCreatorSupport copy: ")).append(copy).toString());
return getProxy(copy.createAopProxy());
}
于是,通过这种方式实现了bean的代理。不过这种方式的缺点也是显而易见的,那就是配置起来相当麻烦。
2. BeanNameAutoProxyCreator
配置方式如下:
<bean id="userService" class="com.aop.service.UserService"/>
<bean id="beforeAdvice" class="com.aop.advice.BeforeAdvice"/>
<bean id="xxxxxx" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property value="beanNames">
<list>
<value>*service</value>
</list>
</property>
<property value="interceptorNames">
<value>beforeAdvice</value>
</property>
</bean>
这个类实现了BeanPostProcessor接口的子接口:SmartInstantiationAwareBeanPostProcessor,
每个被这个类care的类在取得bean实例前,会调用以下方法:
public Object postProcessBeforeInstantiation(Class beanClass, String beanName)
throws BeansException
{
Object cacheKey = getCacheKey(beanClass, beanName);
if(!targetSourcedBeans.contains(cacheKey))
{
if(advisedBeans.contains(cacheKey) || nonAdvisedBeans.contains(cacheKey))
return null;
if(isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName))
{
nonAdvisedBeans.add(cacheKey);
return null;
}
}
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if(targetSource != null)
{
targetSourcedBeans.add(beanName);
Object specificInterceptors[] = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else
{
return null;
}
}
3. <aop:config>标签
通过aop namespace下的一个标签aop:config来实现aop代理,这个也是用起来相当方便的一种配置方式
<bean id="fooService" class="DefaultFooService"/>
<!-- this is the actual advice itself -->
<bean id="profiler" class="SimpleProfiler"/>
<aop:config>
<aop:aspect ref="profiler">
<aop:pointcut id="aopafterMethod"
expression="execution(* FooService.*(..))"/>
<aop:after pointcut-ref="aopafterMethod"
method="afterMethod"/>
<aop:pointcut id="aopBefore"
expression="execution(* FooService.getBefore(String)) and args(myName)"/>
<aop:before pointcut-ref="aopBefore"
method="beforeMethod"/>
</aop:aspect>
</aop:config>
配置很简短,功能很全面。
这种配置方式的原理则是在进行配置文件解析的时候,由AopNameSpaceHandler对此标签进行解析,然后
注册一个“org.springframework.aop.config.internalAutoProxyCreator” bean,这个bean的实现类是:
org/springframework/aop/aspectj/autoproxy/AspectJAwareAdvisorAutoProxyCreator,此类也实现了
BeanPostProcessor接口。
至此,把大致原理分析了一下。当然,分析的不是很详细,有兴趣的朋友可以跟我联系大家一起交流一下。
分享到:
相关推荐
Spring AOP支持三种织入方式:编译时织入、加载时织入和运行时织入。Spring默认使用运行时织入,通过动态代理实现。 6. **代理(Proxy)**:代理是AOP的核心,它是目标对象的增强版本,负责在调用目标方法前后执行...
本篇文章将深入探讨Spring AOP的四种常见实现方式。 一、基于接口的代理(Interface-Based Proxy) 这是Spring AOP最基础的实现方式,适用于目标对象实现了特定接口的情况。Spring会创建一个代理对象,该对象实现...
本文主要介绍几种常见的Spring AOP配置方式,并通过具体的示例来说明每种配置的特点。 #### 二、AOP配置所需基本元素 配置AOP时需要以下三个基本元素: 1. **Advice**:这是实际执行的代码,即我们所说的“切面”...
1. 注解驱动的AOP:这是最常用的实现方式,通过在方法上添加注解(如`@Before`, `@After`, `@Around`, `@AfterReturning`, `@AfterThrowing`)来定义通知,并使用`@Aspect`注解定义切面。 2. XML配置驱动的AOP:...
总的来说,Spring AOP提供了一种优雅的方式来管理横切关注点,使代码更整洁,降低了模块间的耦合。在实际开发中,它可以用于日志记录、权限控制、事务管理等多个场景,极大地提高了代码的可维护性和复用性。
### Spring AOP 几种配置方式详解 #### 一、Spring AOP 概述 Spring AOP(面向切面编程)是一种强大的编程模式,用于在应用程序中管理横切关注点,如日志记录、安全控制等。Spring 提供了多种方式来支持 AOP 的...
2. **Spring AOP实现方式**:Spring提供了两种AOP实现,一种是基于代理(Proxy-based AOP),另一种是基于ASM字节码操作的AspectJ。基于代理的方式简单易用,而AspectJ则更为强大,支持更复杂的切面定义。 3. **...
SpringBoot结合AspectJ实现SpringAOP拦截指定方法的知识点涵盖了多个方面,这包括Spring AOP的基本概念、SpringBoot的应用、切点(Pointcut)与通知(Advice)的定义、自定义注解以及AspectJ的使用。以下是这些知识...
标题中的“API 线索图”可能意味着本文将通过一种图解的方式,即流程图或者类图的形式,来阐述Spring AOP的编程思想和API的使用。 描述中,“小马哥讲 Spring AOP 编程思想”表明这是由一位专家小马哥讲解的内容,...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种强大的方式来实现横切关注点,如日志、事务管理、安全性等,从而使得代码更加模块化和可维护。在本示例中,"springaop.zip" 包含了一个使用XML...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点问题,如日志、事务管理等。在本主题中,我们将深入探讨Spring AOP的注解版,它是基于Java注解的...
在SpringAOP中,有几个关键的概念: 1. 连接点(Joinpoint)是指程序执行中的某个特定位置,如方法的调用前后、抛出异常后。在Spring中,仅支持方法作为连接点。 2. 切点(Pointcut)是用于匹配连接点的表达式,它...
Spring AOP有两种实现方式:代理模式和注解驱动。代理模式分为JDK动态代理和CGLIB代理。JDK动态代理适用于实现了接口的目标对象,它通过实现InvocationHandler接口创建代理对象。而CGLIB代理则是在运行时为类生成...
在Spring AOP中,有以下几个核心概念: 1. 切面(Aspect):切面是AOP的核心,它封装了横切关注点,如日志、事务管理等。一个切面可以包含多个通知(advises)和一个或多个切入点(pointcuts)。 2. 通知(Advice...
在Spring中实现AOP,我们需要在XML配置文件中定义以下几个部分: 1. **配置Spring容器**:首先,确保Spring的配置文件(如`applicationContext.xml`)已经包含了AOP的命名空间,通常添加如下: ```xml xmlns:aop=...
在Spring中实现AOP,一般有两种方式: - **基于接口的动态代理**:如果目标类实现了接口,Spring会使用JDK的动态代理机制,生成一个实现了相同接口的代理类,代理类在调用实际方法前/后执行通知。 - **基于类的...
它提供了一种声明式的 AOP 实现方式,允许开发者使用注解或 XML 配置来定义切面、通知和切点。 在 Spring 中使用 AspectJ 需要进行以下配置: 1. **启用 AspectJ 注解支持**:为了在 Spring 应用中使用 AspectJ ...
Spring AOP通过两种主要实现方式提供切面功能:代理模式(Proxy)和基于注解的切面(Annotation-based AOP)。代理模式下,Spring创建一个目标对象的代理,当调用目标方法时,代理会在前后添加额外的行为。而注解...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统中的交叉关注点,比如日志、事务管理、性能监控等。在这个"spring aop练习"中,我们将深入探讨如何使用注解来...