AOP是面向切面编程,它解决的是在执行a()方法前后,在b()方法前后,有需要统一处理的场景问题,如日志、事务。Spring当前的的AOP是由动态代理机制实现,具体是使用JDK自带的动态代理类或使用CGLib库所提供的动态代理工具实现。如果觉得动态代理技术可能会影响运行速度,还可以使用AspectJ在编译阶段将代码织入的方式实现。
下面通过一个案例来讲解AOP。如果要在service.impl包下的StudentServiceImpl类中的所有方法添加打印日志功能,按照传统方式,则需要:
@Service("stu")
public class StudentServiceImpl implements StudentService {
@Autowired
StudentDao stuDao;
@Override
public List<Student> searchAll() {
System.out.println("方法开始了");
List<Student> list = stuDao.searchAll();
System.out.println("方法结束了");
return list;
}
@Override
public Student search(int id) {
System.out.println("方法开始了");
Student stu = stuDao.search(id);
System.out.println("方法结束了");
return stu;
}
@Override
public boolean add(Student stu) {
System.out.println("方法开始了");
int rs = stuDao.add(stu);
System.out.println("方法结束了");
return rs > 0;
}
@Override
public boolean update(Student stu) {
System.out.println("方法开始了");
int rs = stuDao.update(stu);
System.out.println("方法结束了");
return rs > 0;
}
@Override
public boolean delete(int id) {
System.out.println("方法开始了");
int rs = stuDao.delete(id);
System.out.println("方法结束了");
return rs > 0;
}
}
而AOP是使用如图的思想,将打印日志和业务代码相分离,由Spring内部在运行时再编织在一起:
在util包下定义一个LogPrint类:
@Component
@Aspect
public class LogPrint {
@Before("execution(* service.impl.StudentServiceImpl.*(..))")
public void beign(JoinPoint joinpoint){
System.out.println(joinpoint.getTarget().getClass()+joinpoint.getSignature().getName()+"方法开始了");
}
@After("execution(* service.impl.StudentServiceImpl.*(..))")
public void end(JoinPoint joinpoint){
System.out.println("方法结束了");
}
}
在applicationContext.xml中添加:
<context:component-scan base-package="util" />
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
JoinPoint 参数提供了目标对象、方法、参数等一系列信息。