1、导包
4+2 +2+2 spring(aop aspect) spring依赖包
2、准备目标对象(UserServiceImpl)
package cn.hd.spring_proxy;
public interface UserService {
void add();
void delete();
void update();
void find();
}
package cn.hd.spring_proxy.impl;
import cn.hd.spring_proxy.UserService;
public class UserServiceImpl implements UserService {
@Override
public void add() {
// System.out.println("开启事务");
System.out.println("添加用户");
// System.out.println("提交用户");
}
@Override
public void delete() {
// System.out.println("开启事务");
System.out.println("删除用户");
// System.out.println("提交事务");
}
@Override
public void update() {
// System.out.println("开启事务");
System.out.println("更新用户");
// System.out.println("提交事务");
}
@Override
public void find() {
// System.out.println("开启事务");
System.out.println("查询用户");
// System.out.println("提交事务");
}
}
3、准备通知
package cn.hd.spring_proxy;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAdvice {
public void before(){
System.out.println("在目标方法前调用。");
}
public void afterReturning(){
System.out.println("如果目标对象方法没有出现异常,就会在该方法调用后调用。");
}
public Objectaround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕前在目标方法前都调用。");
Object proceed = pjp.proceed();
System.out.println("环绕后在目标方法后都调用。");
return proceed;
}
public void after(){
System.out.println("目标方法前后,不管有没有异常都调用。");
}
public void throwException(){
System.out.println("目标方法出现异常调用该方法。");
}
}
4、配置applicationContext.xml文件
1、导入约束
(1).直接打入<aop:conf如果有提示,直接打回车,自动帮你导入约束。
(2).如多没有提示,手动导入约束
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
2、配置切入
<aop:config>……</aop:config>
3、配置切入点
<!--配置切入点
execution(那个对象的那个方法:public void cn.hd.spring_proxy.impl.UserServiceImpl.add())
public:可以默认不写
void:可以用*来代替 代表任意的返回值类型 * cn.hd.spring_proxy.impl.UserServiceImpl.add()
所有方法可以用*来代替 * cn.hd.spring_proxy.impl.UserServiceImpl.*()
()里面可能有参数,可以用..来代替 * cn.hd.spring_proxy.impl.UserServiceImpl.*(..)
一般给多个实现类配置切入点,所以可以用*来代替 *cn.hd.spring_proxy.impl.*ServiceImpl.*(..)
impl..代表有可能还有子包 *cn.hd.spring_proxy.impl..*ServiceImpl.*(..)
-->
<aop:pointcut id="pc" expression="execution(*cn.hd.spring_proxy..impl.*ServiceImpl.*(..))"></aop:pointcut>
4、配置切面(将通知织入到对应的切入点)
<!--配置切面-->
<!--织入通知
ref(通知):把某个通知织入到代理对象中
将myAdvice织入到expression中
-->
<aop:aspect ref="myAdvice">
<!--多种方式切入,总共有五种-->
<!--目标调用方法前
pointcut-ref="pc":对应上面的id
method="before":通知中增强的代码
-->
<!--<aop:beforemethod="before" pointcut-ref="pc"></aop:before>-->
<!--不管方法是否出现异常,都执行-->
<!--<aop:aftermethod="after"pointcut-ref="pc"></aop:after>-->
<!--环绕前后调用,如果有异常则不调用环绕后方法,方法中必须有 ProceedingJoinPoint参数-->
<!--<aop:aroundmethod="around"pointcut-ref="pc"></aop:around>-->
<!--如果出现异常就不调用,不出现异常,在方法后调用-->
<!--<aop:after-returningmethod="afterReturning"pointcut-ref="pc"></aop:after-returning>-->
<!--平常都不调用,出现异常才调用-->
<aop:after-throwing method="throwException"pointcut-ref="pc"></aop:after-throwing>
</aop:aspect>
</aop:config>
5、测试代码
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:cn/hd/spring_proxy/applicationContext.xml")
public class Demo {
/*对应配置bean类的名字*/
@Resource(name = "userService")
private UserService userService;
@Test
public void fun1(){
userService.add();
}
}