目录
AOP演示
-
导包
除了4个基础包+2个日志包,还需要导入Spring传统AOP开发包+第三方aspectJ的开发包
Spring传统AOP开发包
spectJ的开发包
-
准备代理对象UserService
public class UserService implements User {
@Override
public void save() {
System.out.println("增加");
}
@Override
public void del() {
System.out.println("删除");
}
@Override
public void update() {
System.out.println("更新");
}
}
-
准备通知
public class MyAdvice {
//前置通知---目标方法运行前调用
public void beforeAd(){
System.out.println("前置通知");
}
//后置通知---目标方法运行后调用,出现异常不会调用
public void afterAd(){
System.out.println("后置通知");
}
//环绕通知---目标方法运行前和运行后调用
public Object aroundAd(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕通知之前的部分");
Object proceed = pjp.proceed(); //调用目标方法
System.out.println("环绕通知之后的部分");
return proceed;
}
//异常通知---目标方法运行异常后调用
public void afterException(){
System.out.println("异常通知");
}
//返回通知---无论目标方法是否出现异常,最终通知都会执行
public void afterReturn(){
System.out.println("返回通知");
}
}
-
配置通知
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd ">
<bean name="userService" class="com.mark.prop.UserServiceImpl"></bean>
<bean name="myAdvice" class="com.mark.prop.MyAdvice"></bean>
<aop:config>
<!-- 配置切入点
public void com.mark.prop.UserServiceImpl.save()
void com.mark.prop.UserServiceImpl.save() //省略共有权限
* com.mark.prop.UserServiceImpl.save() //不限返回值
* com.mark.prop.UserServiceImpl.*() //不限方法名
* com.mark.prop.*ServiceImpl.*(..) //不限参数,以Service结尾即可
* com.mark.prop.。*ServiceImpl.*(..) //检查所有com.mark.prop包下子包满足条件即可
-->
<aop:pointcut expression="execution(* com.mark.prop.*ServiceImpl.*(..))" id="pc"/>
<aop:aspect ref="myAdvice">
<aop:before method="beforeAd" pointcut-ref="pc"/>
<aop:after method="afterAd" pointcut-ref="pc"/>
<aop:around method="aroundAd" pointcut-ref="pc"/>
<aop:after-throwing method="afterException" pointcut-ref="pc"/>
<aop:after-returning method="afterReturn" pointcut-ref="pc"/>
</aop:aspect>
</aop:config>
</beans>
导入aop约束
配置目标代理对象
<bean name="userService" class="com.mark.prop.UserServiceImpl"></bean>
配置通知对象
<bean name="myAdvice" class="com.mark.prop.MyAdvice"></bean>
将通知织入(应用)目标代理对象
最常用表达式execution
* com.mark.prop.*ServiceImpl.*(..) //不限返回类型,不限参数,不限方法名,以ServiceImpl结尾即可
<!-- 配置切入点
public void com.mark.prop.UserServiceImpl.save()
void com.mark.prop.UserServiceImpl.save() //省略共有权限
* com.mark.prop.UserServiceImpl.save() //不限返回值
* com.mark.prop.UserServiceImpl.*() //不限方法名
* com.mark.prop.*ServiceImpl.*(..) //不限参数,以ServiceImpl结尾即可
* com.mark.prop..*ServiceImpl.*(..) //检查所有com.mark.prop包下子包满足条件即可
-->
<aop:config>
<!-- 配置切入点
public void com.mark.prop.UserServiceImpl.save()
void com.mark.prop.UserServiceImpl.save() //省略共有权限
* com.mark.prop.UserServiceImpl.save() //不限返回值
* com.mark.prop.UserServiceImpl.*() //不限方法名
* com.mark.prop.*ServiceImpl.*(..) //不限参数,以Service结尾即可
* com.mark.prop..*ServiceImpl.*(..) //检查所有com.mark.prop包下子包满足条件即可
-->
<aop:pointcut expression="execution(* com.mark.prop.*ServiceImpl.*(..))" id="pc"/>
<aop:aspect ref="myAdvice">
<aop:before method="beforeAd" pointcut-ref="pc"/>
<aop:after method="afterAd" pointcut-ref="pc"/>
<aop:around method="aroundAd" pointcut-ref="pc"/>
<aop:after-throwing method="afterException" pointcut-ref="pc"/>
<aop:after-returning method="afterReturn" pointcut-ref="pc"/>
</aop:aspect>
</aop:config>
-
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserProxyTest {
@Resource(name="userService")
private UserService us;
//不能创建UserServiceImpl us 接口不能被实例化
@Test
public void name() {
us.del();
}
}