AOP的annotation方式的实现(成功)

 

AOP的annotation实现方式是基于AspectJ的实现,需要以下几步:

首先,需要添加AspectJ的包:aspectjrt.jar  aspectweaver.jar

其次,在applicationContext .xml文件中添加配置<aop:aspectj-autoproxy/>,否则不能使用aspectj的语法,在此之前,需要在引入AOP的命名空间xmlns:aop=http://www.springframework.org/schema/aop

再次,添加切面类

@Aspect

@Component

public class LogInterceptor {

@Before("execution(public void com.bjsxt.dao.impl.UserDAOImpl.*(..))")

    public void beforeMethod(){

       System.out.println("method before");

    }

@After("execution(public void com.bjsxt.dao.impl.UserDAOImpl.*(..))")

    public void afterMethod(){

       System.out.println("method after");

    }

@AfterReturning("execution(public * com.bjsxt.dao.impl.UserDAOImpl.*(..))")

    public void afterReturning(){

       System.out.println("method after returning");

    }

@AfterThrowing("execution(public * com.bjsxt.dao.impl.UserDAOImpl.*(..))")

    public void afterThrowing(){

       System.out.println("method throws exception");

    }

@Around("execution(public * com.bjsxt.dao.impl.UserDAOImpl.*(..))")

    public void around(ProceedingJoinPoint pjp) throws Throwable{

       System.out.println("method around start");

       pjp.proceed();

       System.out.println("method around end");

    }

}

@Before("execution(public void com.bjsxt.dao.impl.UserDAOImpl.*(..))")

这句话的意思是:在执行类com.bjsxt.dao.impl.UserDAOImpl中的任何类型的参数,任何返回值为空,访问类型为public的方法之前都会执行beforeMethod()方法。

@AfterThrowing("execution(public * com.bjsxt.dao.impl.UserDAOImpl.*(..))")

这句话所定义的通知是在所调用的函数抛出异常的时候才会调用

@AfterReturning("execution(public * com.bjsxt.dao.impl.UserDAOImpl.*(..))")

这句话所定义的通知是在所调用的函数正常返回的时候才会调用

@After("execution(public void com.bjsxt.dao.impl.UserDAOImpl.*(..))")

这句话定义的通知在程序返回之后(包括正常返回和抛出异常返回)会调用

@Around("execution(public * com.bjsxt.dao.impl.UserDAOImpl.*(..))")

around通知需要一个ProceedingJoinPoint 类型的参数pjp,并且在程序中需调用pjp.proceed();

 

User实体类:

public class User {
 private String username;
 private String password;
 public String getUsername() {
  return username;
 }
 public void setUsername(String username) {
  this.username = username;
 }
 public String getPassword() {
  return password;
 }
 public void setPassword(String password) {
  this.password = password;
 }
}

UserDAO的内容:

public interface UserDAO {
 public void save(User user);
}

UserDAOImpl的内容:

@Component("userDAOImpl")
public class UserDAOImpl implements UserDAO {
 public void save(User user) {
  System.out.println("user saved!");
 }
}

 UserService的内容:

@Component("userService")
public class UserService {
 
 private UserDAO userDAO; 
 public UserDAO getUserDAO() {
  return userDAO;
 }
 @Resource(name="userDAOImpl")
 public void setUserDAO( UserDAO userDAO) {
  this.userDAO = userDAO;
 }
 public void add(User user) {
  userDAO.save(user);
 }
}

测试类的内容(使用Junit测试):

public class UserServiceTest {
 @Test
 public void testAdd() throws Exception {
  ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
  UserService service = (UserService)ctx.getBean("userService");
  service.add(new User());
 }

}

最后,直接执行即可,运行结果:

method around start

method before

user saved!

method around end

method after

method after returning

 

通过观察不难发现,每个通知后面的切入点语法都是一样的,因此,此时可以定义一个切入点,然后不同的通知直接调用即可

@Aspect

@Component

public class LogInterceptor {

    @Pointcut("execution(public * com.bjsxt.dao..*.*(..))")

    public void myMethod(){}

    @Before("myMethod()")

    public void beforeMethod(){

       System.out.println("method before");

    }

    @After("myMethod()")

    public void afterMethod(){

       System.out.println("method after");

    }

    @AfterReturning("myMethod()")

    public void afterReturning(){

       System.out.println("method after returning");

    }

    @AfterThrowing("myMethod()")

    public void afterThrowing(){

       System.out.println("method throws exception");

    }

    @Around("myMethod()")

    public void around(ProceedingJoinPoint pjp) throws Throwable{

       System.out.println("method around start");

       pjp.proceed();

       System.out.println("method around end");

    }

}

运行程序,结果相同:

method around start

method before

user saved!

method around end

method after

method after returning

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值