Spring基础入门五:基于XML和注解的Spring的AOP使用
1。首先基于注解配置的AOP使用:(在学习Spring的AOP之前建意先去学习一下Java的JDK动态代理和CGLIB的代理技术,AOP是基于代理实现的,JDK的动态代理需要目标对象实现一个接口,若没有实现接口则可以使用CGLIB,它的代理对象是继承目标对象。)
目标对象的接口如下:
?
public interface PersonService {public abstract void save(String name);public abstract String getPersonName(String personId);public abstract void deletePerson(Integer id);}
?
目标对象(PersonServiceImple):
public class PersonServiceImple implements PersonService {public void save(String name) {System.out.println("aop.annotation.service.imple.PersonServiceImple的save()方法");// throw new RuntimeException("手动引用的一个异常信息");}public String getPersonName(String personId) {//throw new RuntimeException("手动抛出的异常信息....");return "http://zmx.iteye.com";}public void deletePerson(Integer id){throw new RuntimeException("手动抛出的异常信息....");}}
?使用Spring的注解配置一个Spring的切面
import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;//@Aspect用来标示一个类为切面@Aspectpublic class MyInterceptor {// @Pointcut用来设置一个切入点。aop.annotation.service..包(子包)内的所有类,所有方法,任何参数@Pointcut("execution(* aop.annotation.service.imple..*.*(..))")private void anyMethod() {}// 使用@Before(切入点)用来表示目标方法执行前执行的操作(前置通知)// @Before("anyMethod()")@Before("anyMethod() && args(nameArg)")// 使用这个方法可以获取参数。即:在原来的切入点条件上加了另一个条件即:拦截方法的参数有一个并且是String类型public void doBefore(String nameArg) {System.out.println("前置通知...拦截方法执行参数:" + nameArg);}// 使用@AfterReturning(切入点)用来表示目标方法执行完执行的操作(后置通知)// @AfterReturning("anyMethod()")@AfterReturning(pointcut = "anyMethod()", returning = "returnArg")// 使用这个方法可以获取返回结果。即:在原来的切入点条件上加了另一个条件即:拦截方法的返回值类型是String类型public void doAfterReturning(String returnArg) {System.out.println("后置通知...拦截方法返回结查:" + returnArg);}// 使用@After(切入点)用来表示目标方法执行无论是否出现异常都执行的操作(最终通知)@After("anyMethod()")public void doFinally() {System.out.println("最终通知...");}// 使用@AfterThrowing(切入点)用来表示目标方法执行出现异常时执行的操作(例外通知)// @AfterThrowing("anyMethod()")@AfterThrowing(pointcut = "anyMethod()", throwing = "ex")public void doException(Exception ex) {System.out.println("例外通知...取获异常信息:" + ex);}// 使用@Around(切入点)用来表示整个通知(环绕通知:该方法必须接受一个org.aspectj.lang.ProceedingJoinPoint类型的参数)@Around("anyMethod()")public Object doAround(ProceedingJoinPoint pjp) throws Throwable {System.out.println("环绕通知之前...");Object result = pjp.proceed();System.out.println("环绕通知之后...");return result;}}
?
?在Spring的配置XML中打开对象上述注解的功能和向Spring容器中注册该目标对象
<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-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"><!-- 基于注解方式的声明切面 --><aop:aspectj-autoproxy /><bean id="personService"name="code">public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("beansAOP.xml");PersonService personService = (PersonService) ctx.getBean("personService");//personService.save("小张");//执行参数personService.getPersonName("mengya");//返回结果//personService.deletePerson(123);}
2。首先基于XML配置的AOP使用:
目标对象接口:
public interface PersonService {public abstract void save(String name);public abstract String getPersonName(String personId);public void deletePerson(Integer id);}
?
目标对象:
public class PersonServiceImple implements PersonService {public void save(String name) {System.out.println("aop.xml.service.imple.PersonServiceImple的save()方法");// throw new RuntimeException("手动引用的一个异常信息");}public String getPersonName(String personId) {//throw new RuntimeException("手动抛出的异常信息....");return "http://zmx.iteye.com";}public void deletePerson(Integer id){throw new RuntimeException("手动抛出的异常信息....");}}
?
Spring的切面对象:
public class MyInterceptor {public void doBefore() {System.out.println("前置通知...");}public void doAfterReturning(String returnArg) {System.out.println("后置通知...拦截方法返回结查:" + returnArg);}public void doFinally() {System.out.println("最终通知...");}public void doException(Exception ex) {System.out.println("例外通知...取获异常信息:" + ex);}public Object doAround(ProceedingJoinPoint pjp) throws Throwable {System.out.println("环绕通知之前...");Object[] args = pjp.getArgs();for (int i = 0; i < args.length; i++) {System.out.println(args);}Object result = pjp.proceed();System.out.println("环绕通知之后...");return result;}}
?
在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-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"><bean id="personService"ref="myInterceptor"><aop:pointcut id="myAnyMethod"expression="execution(* aop.xml.service.imple.*.*(..))" /><aop:before pointcut-ref="myAnyMethod" method="doBefore"/><aop:after-returning method="doAfterReturning" pointcut-ref="myAnyMethod" returning="returnArg"/><aop:after-throwing method="doException" pointcut-ref="myAnyMethod" throwing="ex"/><aop:after method="doFinally" pointcut-ref="myAnyMethod"/><aop:around method="doAround" pointcut-ref="myAnyMethod"/></aop:aspect></aop:config></beans>
?测试:
public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("beansAOP2.xml");PersonService personService = (PersonService) ctx.getBean("personService");//personService.save("AOP");personService.getPersonName("123");}
??