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的
-->