Spring AOP部分使用JDK动态代理或者CGLIB来为目标对象创建代理.如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理。所有该目标类型实现的接口都将被代理。 若该目标对象没有实现任何接口,则创建一个CGLIB代理。
接口:com.spring305.test.aopSpring.dao.AopSpringDao.java
public interface AopSpringDao { public void test(); public String test2(String name); }
实现:com.spring305.test.aopSpring.dao.impl.AopSpringDaoImpl.java
public class AopSpringDaoImpl implements AopSpringDao { @Override public void test() { System.out.println(AopSpringDaoImpl.class.getName()+" +====="); } @Override public String test2(String name) { System.out.println(AopSpringDaoImpl.class.getName()+" test2() +====="+name); return name+" in test2()"; } }
定义切面: com.spring305.test.aopSpring.dao.AopInterceptor.java
@Aspect //切面定义完后交给spring管理,XML中的bean配置来交给Spring管理,或者使用自动扫描来 public class AopInterceptor { @Pointcut("execution (* com.spring305.test.aopSpring.dao.impl.AopSpringDaoImpl.*(..))") private void anyMethod(){}//采用方法定义的方式来定义切入点的名字,声明一个切入点 //@Before("anyMethod()")//前置通知里参数写切入点名 @Before("anyMethod()&&args(name)")//前置通知里参数写切入点名 public void beforeAdvice(String name){//有了参数后,则只针对其中参数相匹配的方法 //String name System.out.println("前置通知"+name); } @AfterReturning(pointcut="anyMethod()",returning="revalue") public void returnAdvice(String revalue){ System.out.println("后置通知"+revalue); } @AfterThrowing(pointcut="anyMethod()",throwing="e") public void exceptionAdvice(Exception e){ System.out.println("例外通知"+e.toString()); } @After("anyMethod()") public void releaseAction(){ System.out.println("最终通知"); } @Around("anyMethod()") public Object bacicProfiling(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("环绕通知 进入方法"); Object result = pjp.proceed(); System.out.println("环绕通知 退出方法"); return result; } }
XML:
<aop:aspectj-autoproxy /><!-- 开启切面编程功能 --> <bean id="myInterceptor" class="com.spring305.test.aopSpring.dao.AopInterceptor"></bean> <bean id="aopSpringDao" class="com.spring305.test.aopSpring.dao.impl.AopSpringDaoImpl"></bean>
测试:
@Test//annotation式 public void testAopInterceptorAnnotation(){ ApplicationContext cxt = new ClassPathXmlApplicationContext("testAopSpring.xml"); AopSpringDao aop = (AopSpringDao)cxt.getBean("aopSpringDao"); aop.test(); aop.test2("123"); }
也可以使用XML方式来配置切点;
<bean id="aopSpringDaoImpl"class="com.spring305.test.aopSpring.dao.impl.AopSpringDaoImpl"> </bean> <bean id="aspectBean"class="com.spring305.test.aopSpring.dao.TheInterceptor"> </bean> <aop:config> <aop:aspect id="asp" ref="aspectBean"> <aop:pointcut id="thecut" expression="execution(* com.spring305.test.aopSpring.dao.impl.AopSpringDaoImpl.*(..))" /> <aop:after-returning pointcut-ref="thecut" method="afterReturningRes" returning="result" /> <aop:around pointcut-ref="thecut" method="around" /> <aop:after-throwing pointcut-ref="thecut" method="catchException" throwing="e" /> <aop:after pointcut-ref="thecut" method="after" /> <aop:before pointcut-ref="thecut" method="before" /> </aop:aspect> </aop:config>
<!-- <aop:pointcut id="thecut" expression="execution(void com.spring305.test.aopSpring.dao.impl.AopSpringDaoImpl.*(java.lang.String,..))" /> 参数中第一个为string,后面的不管了,返回为void的 -->