Spring Aop
Aop面向切面編程
Aop入門動態(tài)代理
動態(tài)代理,其實與Aop的原理有些相似,可以用動態(tài)代理來入門。
什么是動態(tài)代理
動態(tài)代理可以提供對另一個對象的訪問,同時隱藏實際對象的具體事實。代理一般會實現(xiàn)它所表示的實際對象的接口。代理可以訪問實際對,不允許直接訪問某些類;對訪問要做特殊處理客戶隱藏了實際對象??蛻舨恢浪桥c代理打交道還是與實際對象打交道。
為什么使用動態(tài)代理
因為動態(tài)代理可以對請求進行任何處理,不允許直接訪問某些類;對訪問要做特殊處理等都需要使用動態(tài)代理進行解決。
動態(tài)代理Demo
public interface ISubject {
void dosomething();
}
public class SubjectImpl implements ISubject {
public void dosomething() {
System.out.println("SubjectImpl is working....");
}
}
public class SubjectLoggingProxy {
private ISubject target;
public SubjectLoggingProxy(ISubject target) {
super();
this.target = target;
}
public ISubject getLoggingProxy(){
ISubject proxy= null;
//代理對象由哪一個類加載器負責
ClassLoader loader = target.getClass().getClassLoader();
//代理對象類型
Class[] interfaces = new Class[]{ISubject.class};
//調(diào)用代理對象,其中的方法時,執(zhí)行的代碼
InvocationHandler h = new InvocationHandler() {
public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
System.out.println(arg1.getName()+"proxy is working ...");
arg1.invoke(target, arg2);
return 0;
}
};
proxy = (ISubject) Proxy.newProxyInstance(loader, interfaces, h);
return proxy;
}
}
public class Main {
public static void main(String[] args) {
ISubject target = new SubjectImpl();
ISubject proxy = new SubjectLoggingProxy(target).getLoggingProxy();
proxy.dosomething();
}
}
Aop好處
- 每個事物邏輯位于一個位置,代碼不分散,便于維護和升級。
- 業(yè)務模塊更加簡潔,只包含核心業(yè)務代碼。
Aop術語
- 切面 Aspect:橫切關注點被模塊化后的特殊對象
- 通知 Advice:切面必須完成的方法
- 目標 Target:被通知的對象
- 代理 Proxy:向目標對象應用通知后創(chuàng)建的對象
- 連接點 Joinpoint:程序執(zhí)行的某個特定位置。類的方法的執(zhí)行前,執(zhí)行后等,有兩個基本信息,1,方法, 2,相對點,那個方法執(zhí)行前或后。
- 切點 pointcut:
AspectJ 基于注解或xml實現(xiàn)AOP
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* spring.aop.impl.*.*(String))")
public void beforeSay(JoinPoint joinPoint){
List<Object> list = Arrays.asList(joinPoint.getArgs());
System.out.println(list);
System.out.println(" zhang zui..............");
System.out.println(joinPoint.getSignature().getName());
}
@After("execution(* spring.aop.impl.*.*(String))")
public void afterSay(){
System.out.println(" bi zui..............");
}
}
<context:component-scan base-package="spring.aop.impl"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
其他要點
- @order(int) 可以標記切面的執(zhí)行順序
- @Pointcut 來聲明切入點表達式,后面的通知直接調(diào)用這個被它標記的方法。
基于xml
<!-- 配置AOP -->
<aop:config>
<!-- 配置切點表達式 -->
<aop:pointcut expression="execution(* spring.aop.xml.Subject.*(String))" id="pointcut"/>
<!-- 配置切面及通知 -->
<aop:aspect ref="loggingAspect" order="1">
<aop:before method="beforeSay" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>