Spring第7章:Spring Aop:
AOP术语
joinpoint:执行点 + 方位
pointcut:具体连接点
advice:功能代码 + 方位
aspect ( advisor ) :advice + pointcut
aop的实现者
aop原理
jdk动态代理
- gclib
⚠️都是运行期间织入
一些对比:
advice增强类型
Spring支持红色五种. 左下角也可以
- 前置增强为例
实现的核心类:
org.springframework.aop.BeforeAdvice
org.springframework.aop.MethodBeforeAdvice
org.springframework.aop.framework.ProxyFactory
实现前置增强接口:
public class GreetingBeforeAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
String clientName = (String) args[0];
System.out.println(“Bonjour! Mr.” + clientName + “.”);
}
}
使用它:
public static void main(String[] args) {
Waiter target = new NaiveWaiter();
BeforeAdvice advice = new GreetingBeforeAdvice(); // 自定义的advice
ProxyFactory proxyFactory = new ProxyFactory(); // 核心
proxyFactory.setTarget(target);
proxyFactory.addAdvice(advice);
Waiter proxy = (Waiter) proxyFactory.getProxy();
proxy.greetTo("Qiuyu");
proxy.serveTo("Qiuyu");
}
在spring中配置它:
<bean id=“greetingAdvice” class=“chap7.pt3.GreetingBeforeAdvice”/>
<bean id=“target” class=“advice.NaiveWaiter”/>
<bean id=“waiter” class=“org.springframework.aop.framework.ProxyFactoryBean”
p:proxyInterfaces=“advice.Waiter”
p:interceptorNames=“greetingAdvice”
p:target-ref=“target”/>
- 后置增强、环绕增强、throw增强都差不多
- introduce增强暂不复习(类级别、非方法级别的; 为其他类添加新方法)
创建切面:主要是准确描述切点pointcut
-
advice已经有逻辑和方位信息了,就差切点了
-
6种切点:…
-
切面类型:
-
pointcutadvisor体系、常用类
-
静态普通方法名匹配:
// 自定义切面
public class GreetingAdvisor extends StaticMethodMatcherPointcutAdvisor {
// 方法匹配规则定义切点
@Override
public boolean matches(Method method, Class<?> targetClass) {
return “greetTo”.equals(method.getName());
}
// 类匹配规则定义切点
@Override
public ClassFilter getClassFilter() {
return new ClassFilter() {
@Override
public boolean matches(Class<?> clazz) {
return Waiter.class.isAssignableFrom(clazz);
}
};
}
}
// 自定义增强,同前
public class GreetinhBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName()+”.”+method.getName());
String clientName = (String) args[0];
System.out.println("How are you! Mr." + clientName + ".");
}
}
<bean id=“waiterTarget” class=“advice.NaiveWaiter”/>
<bean id=“sellerTarget” class=“advice.Seller”/>
<bean id=“greetAdvice2” class=“chap7.pt4.GreetinhBeforeAdvice”/>
<bean id=“greetAdvisor” class=“chap7.pt4.GreetingAdvisor”
p:advice-ref=“greetAdvice2”/>
<bean id=“parent" abstract="true"
class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="greetAdvisor"
p:proxyTargetClass="true"/>
<bean id="waiter2" parent="parent" p:target-ref=“waiterTarget”/>
<bean id=“seller2” parent=“parent” p:target-ref=“sellerTarget”/>
执行:
public static void main(String[] args) {
String configPath = “chap7/spring-aop.xml”;
ApplicationContext context = new ClassPathXmlApplicationContext(configPath);
Waiter waiter = (Waiter) context.getBean(“waiter2”);
Seller seller = (Seller) context.getBean("seller2");
waiter.greetTo("qiuqiu");
waiter.serveTo("gege");
seller.greetTo("jojo");
}
- 静态regx方法匹配:差不多
- 动态暂不复习
- 流程切面暂不复习
- 复合点切面:composablepointcut,暂不复习
- introduce切面:暂不复习
自动创建代理
之前配xml时候,都有org.springframework.aop.framework.ProxyFactoryBean
参与。能不能不要它参与。
- BeanNameAutoProxyCreator
- DefaultAdvisorAutoProxyCreator
注意⚠️:
注意p264,暂未仔细注意。调用链可能会出问题。有一些解决方法