日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AOP框架实现

發(fā)布時間:2025/5/22 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AOP框架实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標準>>>

本文參照《架構探險》一書。

aop 無非是在原有的方法前后加入自定義的代碼。總體思想:

  • 通過cglib或jvm動態(tài)代理技術生成對目標方法的代理類
  • 將容器中的原實例替換為新生成的代理類實例
  • JDK動態(tài)代理只能對實現(xiàn)了接口的類生成代理,而不能針對類 。 CGLIB是針對類實現(xiàn)代理,主要是對指定的類生成一個子類,覆蓋其中的方法 。 因為是繼承,所以該類或方法最好不要聲明成final ,final可以阻止繼承和多態(tài)。

    <aop:aspectj-autoproxy proxy-target-class="true"/> 強制使用cglib做動態(tài)代理

    AOP框架

    public class AopHelper { ...static {try {//從容器中找到代理類和被代理類的關系Map<Class<?>, Set<Class<?>>> proxyMap = createProxyMap();Map<Class<?>, List<Proxy>> targetMap = createTargetMap(proxyMap);for (Map.Entry<Class<?>, List<Proxy>> targetEntry : targetMap.entrySet()) {//1.創(chuàng)建代理類Object proxy = ProxyManager.createProxy(targetEntry.getKey(), targetEntry.getValue());//2.將容器中的class 換為 代理類BeanHelper.setBean(targetEntry.getKey(), proxy);}} catch (Exception e) {LOGGER.error("aop fail",e);}} ... }

    切面類

    @Aspect(Controller.class) public class ControllerAspect extends AspectProxy

    extends AspectProxy 實現(xiàn)父類方法,也就是我們要添加的操作。

    @Aspect(Controller.class) 表示這個代理類代理的是哪個類(具體方法代理規(guī)則可以在代理類方法中判斷,做不同處理)

    從容器中找到代理類和被代理類的關系

    /*** class集合中找到指定切面的集合* @param aspect* @return* @throws Exception*/private static Set<Class<?>> createTargetClassSet(Aspect aspect) throws Exception {Set<Class<?>> targetClassSet = new HashSet<Class<?>>();Class<? extends Annotation> annotation = aspect.value();if (annotation != null && !annotation.equals(Aspect.class)) {targetClassSet.addAll(ClassHelper.getClassSetByAnnotation(annotation));}return targetClassSet;}/*** 找到繼承AspectProxy的代理類* 根據代理類的Aspect注解中value 找到被代理類* 返回代理類和被代理類的映射* proxyClass -> set<targetClass>* @return* @throws Exception*/private static Map<Class<?>, Set<Class<?>>> createProxyMap() throws Exception {Map<Class<?>, Set<Class<?>>> proxyMap = new HashMap<>();//切面類Set<Class<?>> proxyClassSet = ClassHelper.getClassSetBySuper(AspectProxy.class);for (Class<?> proxyCls : proxyClassSet) {if (proxyCls.isAnnotationPresent(Aspect.class)){//繼承了AspectProxy并且被Aspect標注Aspect aspect = proxyCls.getAnnotation(Aspect.class);Set<Class<?>> targetClassSet = createTargetClassSet(aspect);proxyMap.put(proxyCls, targetClassSet);}}//添加事務代理addTransactionProxy(proxyMap);return proxyMap;}private static void addTransactionProxy(Map<Class<?>, Set<Class<?>>> proxyMap) {Set<Class<?>> serviceClassSet = ClassHelper.getClassSetByAnnotation(Service.class);proxyMap.put(TransactionProxy.class, serviceClassSet);}/*** targetClass -> List<proxy instance>* @param proxyMap* @return* @throws Exception*/private static Map<Class<?>, List<Proxy>> createTargetMap(Map<Class<?>, Set<Class<?>>> proxyMap) throws Exception {HashMap<Class<?>, List<Proxy>> targetMap = new HashMap<>();for (Map.Entry<Class<?>, Set<Class<?>>> proxyEntry : proxyMap.entrySet()) {Class<?> proxyClass = proxyEntry.getKey();Set<Class<?>> targetClassSet = proxyEntry.getValue();for (Class<?> targetClass : targetClassSet) {Proxy proxy = (Proxy) proxyClass.newInstance();if (targetMap.containsKey(targetClass)) {targetMap.get(targetClass).add(proxy);} else {List<Proxy> proxyList = new ArrayList<>();proxyList.add(proxy);targetMap.put(targetClass, proxyList);}}}return targetMap;}

    如何創(chuàng)建代理對象

    //cglib 創(chuàng)建代理對象 public class ProxyManager {public static <T> T createProxy(final Class<T> targetClass, final List<Proxy> proxyList) {//CGLib提供創(chuàng)建代理對象,代理對象是一個代理鏈return (T) Enhancer.create(targetClass, new MethodInterceptor() {@Overridepublic Object intercept(Object targetObject, Method targetMethod, Object[] methodParams, MethodProxy methodProxy) throws Throwable {//返回代理對象 代理鏈 的結果return new ProxyChain(targetClass, targetObject, targetMethod, methodProxy, methodParams, proxyList).doProxyChain();}});} }

    代理對象是ProxyChain類型,因為同一個class可能有多個aop需要處理,所以是一條鏈。

    Enhancer.create

    • Cglib的使用方法

    ProxyChain的執(zhí)行

    public class ProxyChain {private final Class<?> targetClass;private final Object targetObject;private final Method targetMethod;private final MethodProxy methodProxy;private final Object[] methodParams;...public Object doProxyChain() throws Throwable {Object methodResult;if (proxyIndex < proxyList.size()) {methodResult = proxyList.get(proxyIndex++).doProxy(this);} else {//最后執(zhí)行目標對象的業(yè)務邏輯//方法代理,參數(shù)只傳入哪個對象,什么參數(shù)methodResult = methodProxy.invokeSuper(targetObject, methodParams);}return methodResult;} }

    代理對象

    切面代理

    public abstract class AspectProxy implements Proxy{private static final Logger LOGGER = LoggerFactory.getLogger(AspectProxy.class);@Overridepublic Object doProxy(ProxyChain proxyChain) throws Throwable {Object result = null;Class<?> targetClass = proxyChain.getTargetClass();Object[] methodParams = proxyChain.getMethodParams();Method targetMethod = proxyChain.getTargetMethod();begin();try {if (intercept(targetClass, targetMethod, methodParams)) {before(targetClass, targetMethod, methodParams);result = proxyChain.doProxyChain();after(targetClass, targetMethod, methodParams, result);} else {result = proxyChain.doProxyChain();}} catch (Exception e) {LOGGER.error("proxy fail",e);error(targetClass, targetMethod, methodParams, e);throw e;} finally {end();}return result;}private void begin() {}public boolean intercept(Class<?> cls, Method method, Object[] params) {return true;}public void before(Class<?> cls, Method method, Object[] params) {}public void after(Class<?> cls, Method method, Object[] params, Object result) {}public void error(Class<?> cls, Method method, Object[] params, Throwable e) {}public void end() {}}

    事務代理

    public class TransactionProxy implements Proxy {//保證同一線程中事務控制相關邏輯只會執(zhí)行一次?private static final ThreadLocal<Boolean> FLAG_HOLDER = new ThreadLocal<Boolean>(){protected Boolean initialValue() {return false;}};@Overridepublic Object doProxy(ProxyChain proxyChain) throws Exception, Throwable {Boolean flag = FLAG_HOLDER.get();Method method = proxyChain.getTargetMethod();Object result = null;if (!flag && method.isAnnotationPresent(Transaction.class)) {FLAG_HOLDER.set(true);try {DatabaseHelper.beginTransaction();LOGGER.debug("begin transaction");result = proxyChain.doProxyChain();DatabaseHelper.commitTransaction();LOGGER.debug("commit transaction");} catch (Exception e) {DatabaseHelper.rollbackTransaction();LOGGER.debug("rollback transaction");throw e;} finally {//DatabaseHelper.closeConnetion();FLAG_HOLDER.remove();}} else {result = proxyChain.doProxyChain();}return result;} }

    FLAG_HOLDER應該是防止事務的嵌套,比如兩個service都標注了@transaction,一個serviceA一個ServiceB, 但是ServiceA中又調用了ServiceB,這樣沒有FLAG_HOLDER就會先啟動A的事務,再啟動B的事務(A的事務還沒完)。加上FLAG_HOLDER就只會啟動A的事務,B看到已經有事務在執(zhí)行就不啟動事務,默認加入了A的事務。

    轉載于:https://my.oschina.net/u/1245414/blog/1539386

    總結

    以上是生活随笔為你收集整理的AOP框架实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。