spring学习参考: https://www.yiibai.com/spring/
为什么要使用Spring?
Spring主要两个有功能为我们的业务对象管理提供了非常便捷的方法:
- DI(Dependency Injection,依赖注入)
- AOP(Aspect Oriented Programming,面向切面编程)
Java Bean
每一个类实现了Bean的规范才可以由Spring来接管,那么Bean的规范是什么呢?
- 必须是个公有(public)类
- 有无参构造函数
- 用公共方法暴露内部成员属性(getter,setter)
实现这样规范的类,被称为Java Bean。即是一种可重用的组件。
DI-依赖注入
简单来说,一个系统中可能会有成千上万个对象。如果要手工维护它们之间的关系,这是不可想象的。我们可以在Spring的XML文件描述它们之间的关系,由Spring自动来注入它们——比如A类的实例需要B类的实例作为参数set进去。
AOP-面向切面编程
就以日志系统为例。在执行某个操作前后都需要输出日志,如果手工加代码,那简直太可怕了。而且等代码庞大起来,也是非常难维护的一种情况。这里就需要面向切面来编程
关于Bean
Bean的生命周期
如你所见,在bean准备就绪之前,bean工厂执行了若干启动步骤。我们对图进行详细描述:
- Spring对bean进行实例化;
- Spring将值和bean的引用注入到bean对应的属性中;
- 如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBean-Name()方法;
- 如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入;
- 如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来;
- 如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessBeforeInitialization()方法;
- 如果bean实现了InitializingBean接口,Spring将调用它们的after-PropertiesSet()方法。类似地,如果bean使用init-method声明了初始化方法,该方法也会被调用;
- 如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessAfterInitialization()方法;
- 此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;
- 如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。
Bean的作用域
Spring定义了多种Bean作用域,可以基于这些作用域创建bean,包括:
- 单例(Singleton):在整个应用中,只创建bean的一个实例。
- 原型(Prototype):每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例。
- 会话(Session):在Web应用中,为每个会话创建一个bean实例。
- 请求(Rquest):在Web应用中,为每个请求创建一个bean实例。
声明Bean
以下是声明Bean的注解:
- @Component 组件,没有明确的角色
- @Service 在业务逻辑层使用
- @Repository 在数据访问层使用
- @Controller 在展现层使用(MVC -> Spring MVC)使用
- 在这里,可以指定bean的id名:Component(“yourBeanName”)
- 同时,Spring支持将@Named作为@Component注解的替代方案。两者之间有一些细微的差异,但是在大多数场景中,它们是可以互相替换的
Spring自动装配Beans
<bean id="customer" class="com.yiibai.common.Customer" autowire="byName" />
- no – 缺省情况下,自动配置是通过“ref”属性手动设定
- byName – 根据属性名称自动装配。如果一个bean的名称和其他bean属性的名称是一样的,将会自装配它。
- byType – 按数据类型自动装配。如果一个bean的数据类型是用其它bean属性的数据类型,兼容并自动装配它。
- constructor – 在构造函数参数的byType方式。
- autodetect – 如果找到默认的构造函数,使用“自动装配用构造”; 否则,使用“按类型自动装配”。
<bean id="customer" class="com.yiibai.common.Customer" autowire="byName" />
Spring 装配
<bean id="customer" class="com.yiibai.common.Customer" > <property name="address" ref="address" /> </bean> <bean id="address" class="com.yiibai.common.Address" > <property name="fulladdress" value="YiLong Road, CA 188" /> </bean>
<bean id="customer" class="com.yiibai.common.Customer" autowire="byName" /> <bean id="address" class="com.yiibai.common.Address" > <property name="fulladdress" value="YiLong Road, CA 188" /> </bean>
构造方法自动装配
Spring装配
<bean id="developer" class="com.yiibai.common.Developer"> <constructor-arg> <ref bean="language" /> </constructor-arg> </bean> <bean id="language" class="com.yiibai.common.Language" > <property name="name" value="Java" /> </bean>
<bean id="developer" class="com.yiibai.common.Developer" autowire="constructor" /> <bean id="language" class="com.yiibai.common.Language" > <property name="name" value="Java" /> </bean>
@Autowired
@Qualifier示例<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> <bean id="CustomerBean" class="com.yiibai.common.Customer"> <property name="action" value="buy" /> <property name="type" value="1" /> </bean> <bean id="PersonBean" class="com.yiibai.common.Person"> <property name="name" value="yiibai" /> <property name="address" value="address ABC" /> <property name="age" value="29" /> </bean> </beans>
package com.yiibai.common; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; public class Customer { @Autowired @Qualifier("personA") private Person person; //... }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <import resource="config/customer.xml"/> <import resource="config/scheduler.xml"/> </beans>
Spring AOP通知实例
-
通知(Advice)之前 - 该方法执行前运行
- 通知(Advice)返回之后 – 运行后,该方法返回一个结果
- 通知(Advice)抛出之后 – 运行方法抛出异常后,
- 环绕通知 – 环绕方法执行运行,结合以上这三个通知。
Spring AOP 通知
1. 之前通知
package com.yiibai.aop; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class HijackBeforeMethod implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("HijackBeforeMethod : Before method hijacked!"); } }
- ‘target’ – 定义你想拦截的bean。
- ‘interceptorNames’ – 定义要应用这个代理/目标对象的类(通知)。
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="customerService" class="com.yiibai.customer.services.CustomerService"> <property name="name" value="Yiibai Mook Kim" /> <property name="url" value="http://www.yiibai.com" /> </bean> <bean id="hijackBeforeMethodBean" class="com.yiibai.aop.HijackBeforeMethod" /> <bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="customerService" /> <property name="interceptorNames"> <list> <value>hijackBeforeMethodBean</value> </list> </property> </bean> </beans>
package com.yiibai.common; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.yiibai.customer.services.CustomerService; public class App { public static void main(String[] args) { ApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] { "Spring-Customer.xml" }); CustomerService cust = (CustomerService) appContext.getBean("customerServiceProxy"); System.out.println("*************************"); cust.printName(); System.out.println("*************************"); cust.printURL(); System.out.println("*************************"); try { cust.printThrowException(); } catch (Exception e) { } } }
输出结果
************************* HijackBeforeMethod : Before method hijacked! Customer name : Yiibai Mook Kim ************************* HijackBeforeMethod : Before method hijacked! Customer website : http://www.yiibai.com ************************* HijackBeforeMethod : Before method hijacked!
package com.yiibai.aop; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class HijackAfterMethod implements AfterReturningAdvice { @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("HijackAfterMethod : After method hijacked!"); } }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="customerService" class="com.yiibai.customer.services.CustomerService"> <property name="name" value="Yong Mook Kim" /> <property name="url" value="http://www.yiibai.com" /> </bean> <bean id="hijackAfterMethodBean" class="com.yiibai.aop.HijackAfterMethod" /> <bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="customerService" /> <property name="interceptorNames"> <list> <value>hijackAfterMethodBean</value> </list> </property> </bean> </beans>
************************* Customer name : Yiibai Mook Kim HijackAfterMethod : After method hijacked! ************************* Customer website : http://www.yiibai.com HijackAfterMethod : After method hijacked! *************************
package com.yiibai.aop; import org.springframework.aop.ThrowsAdvice; public class HijackThrowException implements ThrowsAdvice { public void afterThrowing(IllegalArgumentException e) throws Throwable { System.out.println("HijackThrowException : Throw exception hijacked!"); } }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="customerService" class="com.yiibai.customer.services.CustomerService"> <property name="name" value="Yong Mook Kim" /> <property name="url" value="http://www.yiibai.com" /> </bean> <bean id="hijackThrowExceptionBean" class="com.yiibai.aop.HijackThrowException" /> <bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="customerService" /> <property name="interceptorNames"> <list> <value>hijackThrowExceptionBean</value> </list> </property> </bean> </beans>
************************* Customer name : Yiibai Mook Kim ************************* Customer website : http://www.yiibai.com ************************* HijackThrowException : Throw exception hijacked!
它结合了上面的三个通知,在方法执行过程中执行。创建一个实现了MethodInterceptor接口的类。必须调用“methodInvocation.proceed();” 继续在原来的方法执行,否则原来的方法将不会执行。
package com.yiibai.aop; import java.util.Arrays; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class HijackAroundMethod implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("Method name : " + methodInvocation.getMethod().getName()); System.out.println("Method arguments : " + Arrays.toString(methodInvocation.getArguments())); // same with MethodBeforeAdvice System.out.println("HijackAroundMethod : Before method hijacked!"); try { // proceed to original method call Object result = methodInvocation.proceed(); // same with AfterReturningAdvice System.out.println("HijackAroundMethod : Before after hijacked!"); return result; } catch (IllegalArgumentException e) { // same with ThrowsAdvice System.out.println("HijackAroundMethod : Throw exception hijacked!"); throw e; } } }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="customerService" class="com.yiibai.customer.services.CustomerService"> <property name="name" value="Yong Mook Kim" /> <property name="url" value="http://www.yiibai.com" /> </bean> <bean id="hijackAroundMethodBean" class="com.yiibai.aop.HijackAroundMethod" /> <bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="customerService" /> <property name="interceptorNames"> <list> <value>hijackAroundMethodBean</value> </list> </property> </bean> </beans>
************************* Method name : printName Method arguments : [] HijackAroundMethod : Before method hijacked! Customer name : YiiBai Mook Kim HijackAroundMethod : Before after hijacked! ************************* Method name : printURL Method arguments : [] HijackAroundMethod : Before method hijacked! Customer website : http://www.yiibai.com HijackAroundMethod : Before after hijacked! ************************* Method name : printThrowException Method arguments : [] HijackAroundMethod : Before method hijacked! HijackAroundMethod : Throw exception hijacked!
总结
1.切入点 - 名称匹配的例子
File : HijackAroundMethod.java
package com.yiibai.aop; import java.util.Arrays; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class HijackAroundMethod implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("Method name : " + methodInvocation.getMethod().getName()); System.out.println("Method arguments : " + Arrays.toString(methodInvocation.getArguments())); System.out.println("HijackAroundMethod : Before method hijacked!"); try { Object result = methodInvocation.proceed(); System.out.println("HijackAroundMethod : Before after hijacked!"); return result; } catch (IllegalArgumentException e) { System.out.println("HijackAroundMethod : Throw exception hijacked!"); throw e; } } }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="customerService" class="com.yiibai.customer.services.CustomerService"> <property name="name" value="Yiibai" /> <property name="url" value="http://www.yiibai.com" /> </bean> <bean id="hijackAroundMethodBeanAdvice" class="com.yiibai.aop.HijackAroundMethod" /> <bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="customerService" /> <property name="interceptorNames"> <list> <value>customerAdvisor</value> </list> </property> </bean> <bean id="customerYiibaicut" class="org.springframework.aop.support.NameMatchMethodYiibaicut"> <property name="mappedName" value="printName" /> </bean> <bean id="customerAdvisor" class="org.springframework.aop.support.DefaultYiibaicutAdvisor"> <property name="pointcut" ref="customerYiibaicut" /> <property name="advice" ref="hijackAroundMethodBeanAdvice" /> </bean> </beans>
也可以通过使用正则表达式匹配切入点方法的名称 – RegexpMethodYiibaicutAdvisor.
<bean id="customerAdvisor" class="org.springframework.aop.support.RegexpMethodYiibaicutAdvisor"> <property name="patterns"> <list> <value>.*URL.*</value> </list> </property> <property name="advice" ref="hijackAroundMethodBeanAdvice" /> </bean>
现在,它拦截方法名称中有“URL”的方法。在实践中,可以用它来管理DAO层,声明“.*DAO.*” 拦截所有的DAO类来支持事务。
Spring AOP拦截器的序列
<bean id="testAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="interceptorNames"> <list> <idref bean="matchGenericTxInterceptor" /> <idref bean="urlInterceptorInsert" /> <idref bean="urlInterceptorCommit" /> <idref bean="urlInterceptorRelease" /> </list> </property> <property name="beanNames"> <list> <idref local="urlBo" /> </list> </property> </bean>
注 Spring AOP的拦截器的顺序对功能有影响。
Spring AOP+AspectJ注解实例
- @Before – 方法执行前运行
- @After – 运行在方法返回结果后
- @AfterReturning – 运行在方法返回一个结果后,在拦截器返回结果。
- @AfterThrowing – 运行方法在抛出异常后,
- @Around – 围绕方法执行运行,结合以上这三个通知。
启用AspectJ
File : applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <aop:aspectj-autoproxy /> <bean id="customerBo" class="com.yiibai.customer.bo.impl.CustomerBoImpl" /> <!-- Aspect --> <bean id="logAspect" class="com.yiibai.aspect.LoggingAspect" /> </beans>
AspectJ @Before
File : LoggingAspect.java
package com.yiibai.aspect; import org.aspectj.lang.JoinYiibai; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class LoggingAspect { @Before("execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))") public void logBefore(JoinYiibai joinYiibai) { System.out.println("logBefore() is running!"); System.out.println("hijacked : " + joinYiibai.getSignature().getName()); System.out.println("******"); } }
AspectJ @After
File : LoggingAspect.java
package com.yiibai.aspect; import org.aspectj.lang.JoinYiibai; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.After; @Aspect public class LoggingAspect { @After("execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))") public void logAfter(JoinYiibai joinYiibai) { System.out.println("logAfter() is running!"); System.out.println("hijacked : " + joinYiibai.getSignature().getName()); System.out.println("******"); } }
ectJ @AfterReturning
在下面例子中,logAfterReturning()方法将在 customerBo 接口的addCustomerReturnValue()方法执行之后执行。此外,还可以截取返回的值使用“returning”属性。
File : LoggingAspect.java
package com.yiibai.aspect; import org.aspectj.lang.JoinYiibai; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.AfterReturning; @Aspect public class LoggingAspect { @AfterReturning( pointcut = "execution(* com.yiibai.customer.bo.CustomerBo.addCustomerReturnValue(..))", returning= "result") public void logAfterReturning(JoinYiibai joinYiibai, Object result) { System.out.println("logAfterReturning() is running!"); System.out.println("hijacked : " + joinYiibai.getSignature().getName()); System.out.println("Method returned value is : " + result); System.out.println("******"); } }
AspectJ @AfterReturning
File : LoggingAspect.java
package com.yiibai.aspect; import org.aspectj.lang.JoinYiibai; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.AfterThrowing; @Aspect public class LoggingAspect { @AfterThrowing( pointcut = "execution(* com.yiibai.customer.bo.CustomerBo.addCustomerThrowException(..))", throwing= "error") public void logAfterThrowing(JoinYiibai joinYiibai, Throwable error) { System.out.println("logAfterThrowing() is running!"); System.out.println("hijacked : " + joinYiibai.getSignature().getName()); System.out.println("Exception : " + error); System.out.println("******"); } }
AspectJ @Around
在下面例子中,logAround()方法将在customerBo接口的addCustomerAround()方法执行之前执行, 必须定义“joinYiibai.proceed();” 控制何时拦截器返回控制到原来的addCustomerAround()方法。
File : LoggingAspect.java
package com.yiibai.aspect; import org.aspectj.lang.ProceedingJoinYiibai; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Around; @Aspect public class LoggingAspect { @Around("execution(* com.yiibai.customer.bo.CustomerBo.addCustomerAround(..))") public void logAround(ProceedingJoinYiibai joinYiibai) throws Throwable { System.out.println("logAround() is running!"); System.out.println("hijacked method : " + joinYiibai.getSignature().getName()); System.out.println("hijacked arguments : " + Arrays.toString(joinYiibai.getArgs())); System.out.println("Around before is running!"); joinYiibai.proceed(); //continue on the intercepted method System.out.println("Around after is running!"); System.out.println("******"); } }
package com.yiibai.customer.bo; public interface CustomerBo { void addCustomer(); String addCustomerReturnValue(); void addCustomerThrowException() throws Exception; void addCustomerAround(String name); }
1. AspectJ <aop:before> = @Before
AspectJ @Before 示例.
package com.yiibai.aspect; import org.aspectj.lang.JoinYiibai; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class LoggingAspect { @Before("execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))") public void logBefore(JoinYiibai joinYiibai) { //... } }
在XML同等功能,使用 <aop:before>.
<!-- Aspect --> <bean id="logAspect" class="com.yiibai.aspect.LoggingAspect" /> <aop:config> <aop:aspect id="aspectLoggging" ref="logAspect" > <!-- @Before --> <aop:pointcut id="pointCutBefore" expression="execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))" /> <aop:before method="logBefore" pointcut-ref="pointCutBefore" /> </aop:aspect> </aop:config>
2. AspectJ <aop:after> = @After
AspectJ @After 示例.
package com.yiibai.aspect; import org.aspectj.lang.JoinYiibai; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.After; @Aspect public class LoggingAspect { @After("execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))") public void logAfter(JoinYiibai joinYiibai) { //... } }
在XML同等功能,使用 <aop:after>实现。
<!-- Aspect --> <bean id="logAspect" class="com.yiibai.aspect.LoggingAspect" /> <aop:config> <aop:aspect id="aspectLoggging" ref="logAspect" > <!-- @After --> <aop:pointcut id="pointCutAfter" expression="execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))" /> <aop:after method="logAfter" pointcut-ref="pointCutAfter" /> </aop:aspect> </aop:config>
3. AspectJ <aop:after-returning> = @AfterReturning
AspectJ @AfterReturning 示例.
package com.yiibai.aspect; import org.aspectj.lang.JoinYiibai; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.AfterReturning; @Aspect public class LoggingAspect { @AfterReturning( pointcut = "execution(* com.yiibai.customer.bo.CustomerBo.addCustomerReturnValue(..))", returning= "result") public void logAfterReturning(JoinYiibai joinYiibai, Object result) { //... } }
在XML同等功能 - 使用 <aop:after-returning>.
<!-- Aspect --> <bean id="logAspect" class="com.yiibai.aspect.LoggingAspect" /> <aop:config> <aop:aspect id="aspectLoggging" ref="logAspect" > <!-- @AfterReturning --> <aop:pointcut id="pointCutAfterReturning" expression="execution(* com.yiibai.customer.bo.CustomerBo.addCustomerReturnValue(..))" /> <aop:after-returning method="logAfterReturning" returning="result" pointcut-ref="pointCutAfterReturning" /> </aop:aspect> </aop:config>
4. AspectJ <aop:after-throwing> = @AfterReturning
AspectJ @AfterReturning 示例.
package com.yiibai.aspect; import org.aspectj.lang.JoinYiibai; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.AfterThrowing; @Aspect public class LoggingAspect { @AfterThrowing( pointcut = "execution(* com.yiibai.customer.bo.CustomerBo.addCustomerThrowException(..))", throwing= "error") public void logAfterThrowing(JoinYiibai joinYiibai, Throwable error) { //... } }
在XML同等功能 - 使用 <aop:after-throwing>.
<!-- Aspect --> <bean id="logAspect" class="com.yiibai.aspect.LoggingAspect" /> <aop:config> <aop:aspect id="aspectLoggging" ref="logAspect" > <!-- @AfterThrowing --> <aop:pointcut id="pointCutAfterThrowing" expression="execution(* com.yiibai.customer.bo.CustomerBo.addCustomerThrowException(..))" /> <aop:after-throwing method="logAfterThrowing" throwing="error" pointcut-ref="pointCutAfterThrowing" /> </aop:aspect> </aop:config>
5. AspectJ <aop:after-around> = @Around
AspectJ @Around 示例.
package com.yiibai.aspect; import org.aspectj.lang.ProceedingJoinYiibai; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Around; @Aspect public class LoggingAspect { @Around("execution(* com.yiibai.customer.bo.CustomerBo.addCustomerAround(..))") public void logAround(ProceedingJoinYiibai joinYiibai) throws Throwable { //... } }
在XML同等功能 - 使用 <aop:after-around>.
<!-- Aspect --> <bean id="logAspect" class="com.yiibai.aspect.LoggingAspect" /> <aop:config> <aop:aspect id="aspectLoggging" ref="logAspect" > <!-- @Around --> <aop:pointcut id="pointCutAround" expression="execution(* com.yiibai.customer.bo.CustomerBo.addCustomerAround(..))" /> <aop:around method="logAround" pointcut-ref="pointCutAround" /> </aop:aspect> </aop:config>
完整的 XML 实例
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <aop:aspectj-autoproxy /> <bean id="customerBo" class="com.yiibai.customer.bo.impl.CustomerBoImpl" /> <!-- Aspect --> <bean id="logAspect" class="com.yiibai.aspect.LoggingAspect" /> <aop:config> <aop:aspect id="aspectLoggging" ref="logAspect"> <!-- @Before --> <aop:pointcut id="pointCutBefore" expression="execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))" /> <aop:before method="logBefore" pointcut-ref="pointCutBefore" /> <!-- @After --> <aop:pointcut id="pointCutAfter" expression="execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))" /> <aop:after method="logAfter" pointcut-ref="pointCutAfter" /> <!-- @AfterReturning --> <aop:pointcut id="pointCutAfterReturning" expression="execution(* com.yiibai.customer.bo.CustomerBo.addCustomerReturnValue(..))" /> <aop:after-returning method="logAfterReturning" returning="result" pointcut-ref="pointCutAfterReturning" /> <!-- @AfterThrowing --> <aop:pointcut id="pointCutAfterThrowing" expression="execution(* com.yiibai.customer.bo.CustomerBo.addCustomerThrowException(..))" /> <aop:after-throwing method="logAfterThrowing" throwing="error" pointcut-ref="pointCutAfterThrowing" /> <!-- @Around --> <aop:pointcut id="pointCutAround" expression="execution(* com.yiibai.customer.bo.CustomerBo.addCustomerAround(..))" /> <aop:around method="logAround" pointcut-ref="pointCutAround" /> </aop:aspect> </aop:config> </beans>