1.AOP叫做面向切面编程。
2.AOP是对OOP(面向对象编程)的补充。
3.AOP的核心是切面。就是对某个切入点做了通知进行增强扩展,形成横切面。可以实现在 不修改原有代码的情况下,做额外扩展。
4.AOP是对loC的补充。基于动态代理设计模式。
Aspect:切面。为方法添加增强功能的过程。
join point:切入点。就是我们平时说的目标方法,或说对哪个方法做扩展,做增强。
Advice:通知。就是增强内容。
Pointcut:切点。就是表达式(通过切点表达式可以找到需要增强功能的方法),通过表达 式说明哪些方法是join point。
AOP Proxy:代理。Spring支持JDK动态代理和cglib动态代理两种方式,可以通过proxy- target-class=true把默认的JDK动态代理修改为Cglib动态代理。
Weaving:织入。织入就是把Advice添加到join point的过程。
在实际开发中AOP主要应用在Service层。
之后Servlet调用的Service就是调的代理对象
在Spring中提供了两种方式实现AOP:
Schema-based:所有的通知都需要实现特定类型的接口实现通知。
AspectJ:可以使用普通Java类结合特定的配置实现通知
注意:它俩默认都是使用的JDK动态代理,但是同时也支持cglib动态代理。
前置通知:在切入点之前执行的增强功能。通知需要实现MethodBeforeAdvice接口。
后置通知:在切入点之后执行的增强功能。通知需要实现AfterReturningAdvice接口。
环绕通知:一个方法包含了前置通知和后置通知的功能。通知需要实现MethodInterceptor接口。
异常通知:如果切入点中出现了异常(绝对不能try...catch解决了异常)就会触发异常通知。通知需要实现ThrowsAdvice接口。(实现接口,但是接口没有需要重写的方法但是我们要加入这个方法public void afterThrowing(Exception e){} 才行)
实例一:织入前置通知(实现MethodBeforeAdvice接口。)
接口
public interface UserService {
void method();
}
实现类 (直接利用注解将实现类交给spring容器管理)
@Service
public class UserServiceImpl implements UserService {
@Override
public void method() {
System.out.println("目标对象方法执行");
}
}
被织入的通知(利用注解交给容器管理)
@Component
public class BeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("这是前置通知");
System.out.println("目标方法"+method);
}
}
Spring中的配置
测试
写UserService userService 是由于默认是由Jdk实现的动态代理(基于接口)
将其切换成CJLIB之后就可以写成 UserServiceImpl userService了(基于实现类继承)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test3 {
@Autowired
private UserService userService;
@Test
public void aa(){
//此时userService就是代理对象(结合了目标对象和通知对象)
userService.method();
}
}
接口
public interface UserService {
void method();
}
实现类 (直接利用注解将实现类交给spring容器管理)
@Service
public class UserServiceImpl implements UserService {
@Override
public void method() {
System.out.println("目标对象方法执行");
}
}
被织入的通知的类(可以在类中写多个方法,再在配置中引用实现各种通知)(这儿我没用注解)
public class MyAdvice {
//前置通知
public void before(){
System.out.println("前置通知");
}
}
配置文件
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext1.xml")
public class Test4 {
@Autowired
private UserService userService;
@Test
public void aa(){
userService.method();
}
}