多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php框架 > 框架設計 > Spring AOP 實現

Spring AOP 實現

來源:程序員人生   發布時間:2016-07-13 08:17:37 閱讀次數:3929次
    Aop是Aspect-Oriented Programming(面向方面編程或面向切面編程)的簡稱。在Spring平臺功能中,AOP是1個核心模塊,Spring將AOP框架與IoC容器緊密集成,從而為使用AOP提供最大便利。
     AOP可以說是OOP(Object-Oriented Programing,面向對象編程)的補充和完善。OOP引入封裝、繼承和多態性等概念來建立1種對象層次結構,用以摹擬公共行動的1個集合。當我們需要為分散的對象引入公共行動的時候,OOP則顯得無能為力。也就是說,OOP允許你定義從上到下的關系,但其實不合適定義從左到右的關系。例如日志功能。日志代碼常常水平地散布在所有對象層次中,而與它所散布到的對象的核心功能毫無關系。對其他類型的代碼,如安全性、異常處理和透明的延續性也是如此。這類散布在各處的無關的代碼被稱為橫切(cross-cutting)代碼,在OOP設計中,它致使了大量代碼的重復,而不利于各個模塊的重用。
      AOP技術則恰恰相反,它利用1種稱為“橫切”的技術,剖解開封裝的對象內部,并將那些影響了多個類的公共行動封裝到1個可重用模塊,并將其名為“Aspect”,即方面。所謂“方面”,簡單地說,就是將那些與業務無關,卻為業務模塊所共同調用的邏輯或責任封裝起來,便于減少系統的重復代碼,下降模塊間的耦合度,并有益于未來的可操作性和可保護性。
   Spring AOP實現中,使用Java語言來實現增強對象與切面增強利用,并為這二者的結合提供了配置環境。
1、經常使用Spring AOP 的兩種方式實現
     通常使用Spring AOP主要有兩種方式,1種是基于xml配置的純POJO切面方式,另外一種是通過@AspectJ注解驅動的切面方式。如果是純POJO切面的配置AOP,我們需要在Spring容器xml資源定義文件中聲明切面bean,并將切面、切點和通知配置信息通<aop:config>標簽加以說明。如果是@AspectJ注解驅動的切面,我們知道為了支持注解,我們需要在配置文件中加入<aop:aspectj-autoproxy />標簽。不論何種情勢,Spring容器在處理切面時的思路是1致的,在Spring容器的初始化進程中,當載入、解析配置文件中的這些標簽,都需要動態的通過自定義標簽機制解析這些標簽,從而生成相應的BeanDefine。
 1)Spring Aop 自定義標簽處理
    在類AopNamespaceHandler中,源碼以下:
public class AopNamespaceHandler extends NamespaceHandlerSupport {
public AopNamespaceHandler() {
    }

public void init() {
this.registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
        this.registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
        this.registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
        this.registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
}
   在init()函數中,注冊了ConfigBeanDefinitionParser()用于解析處理純POJO切面方式<aop:config>標簽,然后注冊了AspectJAutoProxyBeanDefinitionParser()用于解析處理<aop:aspectj-autoproxy />標簽。
2)注冊Aop自動代理創建器
   不論是  ConfigBeanDefinitionParser還是AspectJAutoProxyBeanDefinitionParser,他們都是實現BeanDefinitionParse接口,主要的方法是BeanDefinition parse(Element elementParserContext parserContext)。

ConfigBeanDefinitionParser的parse()方法:
public BeanDefinition parse(Element element, ParserContext parserContext) {
    CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
    parserContext.pushContainingComponent(compositeDef);
 this.configureAutoProxyCreator(parserContext, element);
    List childElts = DomUtils.getChildElements(element);
    Iterator var5 = childElts.iterator();

    while(var5.hasNext()) {
        Element elt = (Element)var5.next();
        String localName = parserContext.getDelegate().getLocalName(elt);
        if("pointcut".equals(localName)) {
            this.parsePointcut(elt, parserContext);
        } else if("advisor".equals(localName)) {
            this.parseAdvisor(elt, parserContext);
        } else if("aspect".equals(localName)) {
            this.parseAspect(elt, parserContext);
        }
    }

    parserContext.popAndRegisterContainingComponent();
    return null;
}
 在該函數中首先注冊AutoProxyCreator,然后根據不同切面元素解析成為響應的BeanDefinition。this.configureAutoProxyCreator(parserContextelement);終究會履行
public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source);
}
注冊AspectJAwareAdvisorAutoProxyCreator。

AspectJAutoProxyBeanDefinitionParser的parse()方法:
public BeanDefinition parse(Element element, ParserContext parserContext) {
 AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
    this.extendBeanDefinition(element, parserContext);
    return null;
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
可以看到,一樣的注冊AspectJAnnotationAutoProxyCreator,不同于之前的是,AspectJAnnotationAutoProxyCreator繼承自AspectJAwareAdvisorAutoProxyCreator,添加了對注解的處理。

3)AutoProxyCreator類繼承體系

     通過類的繼承體系,可以看到AutoProxyCreator類實現了BeanPostProcessor接口,其實際是1
InstantiationAwareBeanPostProcessor。在bean的生命周期中,可以知道,當容器注冊了BeanPostProcessor類型的bean后,從容器中獲得任何的bean,都將經過BeanPostProcessor相干方法的處理。那末,當1個bean,被切入切面,進行功能增強時,也是通過InstantiationAwareBeanPostProcessor相干方法對這個bean進行處理,具體就是通過代理方式,將切面植入方法調用流程。而這個處理方法就是 Object postProcessAfterInitialization(Object beanString beanName)。

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if(bean != null) { Object cacheKey = this.getCacheKey(bean.getClass(), beanName); if(!this.earlyProxyReferences.contains(cacheKey)) { return this.wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
在this.wrapIfNecessary(beanbeanNamecacheKey)中封裝bean生成代理對象返回。

4)生成代理相干類繼承體系


   在生成代理對象時,通過ProxyFactory類Object getProxy(TargetSource targetSource)方法生成,targetSource是被代理的對象bean封裝。
public static Object getProxy(TargetSource targetSource) {
if(targetSource.getTargetClass() == null) {
throw new IllegalArgumentException("Cannot create class proxy for TargetSource with null target class");
} else {
        ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTargetSource(targetSource);
proxyFactory.setProxyTargetClass(true);
        return proxyFactory.getProxy();
}
}
終究調用DefaultAopProxyFactory類的AopProxy createAopProxy(AdvisedSupport config)方法:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if(!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
        Class targetClass = config.getTargetClass();
        if(targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
} else {
return (AopProxy)(targetClass.isInterface()?new JdkDynamicAopProxy(config):new ObjenesisCglibAopProxy(config));
}
    }
}
Spring提供了兩種方式來生成代理對象: JDKProxy和Cglib,具體使用哪一種方式生成由AopProxyFactory根據AdvisedSupport對象的配置來決定。默許的策略是如果目標類是接口,則使用JDK動態代理技術,否則使用Cglib來生成代理。
  而JdkDynamicAopProxy是標準的java動態代理使用方式,可以看到其實現了InvocationHandler接口。在JdkDynamicAopProxy中,通過Object getProxy(ClassLoader classLoader)函數,獲得代理:
public Object getProxy(ClassLoader classLoader) {
if(logger.isDebugEnabled()) {
        logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}

    Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
    this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
我們知道InvocationHandler是JDK動態代理的核心,生成的代理對象的方法調用都會拜托到InvocationHandler.invoke()方法。
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object oldProxy = null;
    boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class targetClass = null;
Object target = null;

Object retVal;
    try {
      //eqauls()方法,具目標對象未實現此方法 
if(!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
            Boolean retVal2 = Boolean.valueOf(this.equals(args[0]));
            return retVal2;
}
 //hashCode()方法,具目標對象未實現此方法  
if(!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
            Integer retVal1 = Integer.valueOf(this.hashCode());
            return retVal1;
}
 //Advised接口或其父接口中定義的方法,直接反射調用,不利用通知  
if(this.advised.opaque || !method.getDeclaringClass().isInterface() || !method.getDeclaringClass().isAssignableFrom(Advised.class)) {
if(this.advised.exposeProxy) {
                oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
 //取得目標對象的類  
            target = targetSource.getTarget();
            if(target != null) {
                targetClass = target.getClass();
}
 //獲得可以利用到此方法上的Interceptor列表  List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); if(chain.isEmpty()) {   //如果沒有可以利用到此方法的通知(Interceptor),此直接反射調用 method.invoke(target, args) 
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
} else {
           //創建MethodInvocation ,封裝 Interceptor調用鏈

 ReflectiveMethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
         //調用proceed()方法, 順次履行 Interceptor調用鏈 retVal = invocation.proceed(); }

            Class returnType = method.getReturnType();
            if(retVal != null && retVal == target && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
                retVal = proxy;
} else if(retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
}

            Object var13 = retVal;
            return var13;
}

        retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
} finally {
if(target != null && !targetSource.isStatic()) {
            targetSource.releaseTarget(target);
}

if(setProxyContext) {
            AopContext.setCurrentProxy(oldProxy);
}

    }

return retVal;
}
通過this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)方法,獲得通知攔截器鏈
public ListgetInterceptorsAndDynamicInterceptionAdvice(Method method, Class targetClass) {
//這里使用了cache,利用cache獲得已有了的intercepter
AdvisedSupport.MethodCacheKey cacheKey = new AdvisedSupport.MethodCacheKey(method);
List cached = (List)this.methodCache.get(cacheKey);
if(cached == null) {
//這里是利用DefaultAdvisorChainFactory,獲得intercepter鏈
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
    return cached;
}
					
DefaultAdvisorChainFactory類(生成連接器的工廠)中:
public ListgetInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class targetClass) {
    ArrayList interceptorList = new ArrayList(config.getAdvisors().length);
    Class actualClass = targetClass != null?targetClass:method.getDeclaringClass();
    boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
    AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
    Advisor[] var8 = config.getAdvisors();
    int var9 = var8.length;

    for(int var10 = 0; var10 < var9; ++var10) { Advisor advisor = var8[var10]; MethodInterceptor[] interceptors1; if(advisor instanceof PointcutAdvisor) { PointcutAdvisor interceptors = (PointcutAdvisor)advisor; if(config.isPreFiltered() || interceptors.getPointcut().getClassFilter().matches(actualClass)) { interceptors1 = registry.getInterceptors(advisor); MethodMatcher mm = interceptors.getPointcut().getMethodMatcher(); if(MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) { if(mm.isRuntime()) { MethodInterceptor[] var15 = interceptors1; int var16 = interceptors1.length; for(int var17 = 0; var17 < var16; ++var17) { MethodInterceptor interceptor = var15[var17]; interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm)); } } else { interceptorList.addAll(Arrays.asList(interceptors1)); } } } } else if(advisor instanceof IntroductionAdvisor) { IntroductionAdvisor var19 = (IntroductionAdvisor)advisor; if(config.isPreFiltered() || var19.getClassFilter().matches(actualClass)) { interceptors1 = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors1)); } } else { MethodInterceptor[] var20 = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(var20)); } } return interceptorList; }
在這個函數中,首先設置1個List,用于保存最后返回的interceptorList, 然后DefaultAdvisorChainFactory會通過1個AdvisorAdapterRegistry 來實現攔截器的注冊,將配置中Advice適配包裝為interceptor,終究返回。
通過 GlobalAdvisorAdapterRegistry.getInstance()獲得
AdvisorAdapterRegistry registry。 
GlobalAdvisorAdapterRegistry應用單例模式:其實例是DefaultAdvisorAdapterRegistry類對象:
public abstract class GlobalAdvisorAdapterRegistry {
    private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();

    public GlobalAdvisorAdapterRegistry() {
    }

    public static AdvisorAdapterRegistry getInstance() {
        return instance;
    }

    static void reset() {
        instance = new DefaultAdvisorAdapterRegistry();
    }
}

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable { private final Listadapters = new ArrayList(3); public DefaultAdvisorAdapterRegistry() { this.registerAdvisorAdapter(new MethodBeforeAdviceAdapter()); this.registerAdvisorAdapter(new AfterReturningAdviceAdapter()); this.registerAdvisorAdapter(new ThrowsAdviceAdapter()); } public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException { if(adviceObject instanceof Advisor) { return (Advisor)adviceObject; } else if(!(adviceObject instanceof Advice)) { throw new UnknownAdviceTypeException(adviceObject); } else { Advice advice = (Advice)adviceObject; if(advice instanceof MethodInterceptor) { return new DefaultPointcutAdvisor(advice); } else { Iterator var3 = this.adapters.iterator(); AdvisorAdapter adapter; do { if(!var3.hasNext()) { throw new UnknownAdviceTypeException(advice); } adapter = (AdvisorAdapter)var3.next(); } while(!adapter.supportsAdvice(advice)); return new DefaultPointcutAdvisor(advice); } } } public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { ArrayList interceptors = new ArrayList(3); Advice advice = advisor.getAdvice(); if(advice instanceof MethodInterceptor) { interceptors.add((MethodInterceptor)advice); } Iterator var4 = this.adapters.iterator(); while(var4.hasNext()) { AdvisorAdapter adapter = (AdvisorAdapter)var4.next(); if(adapter.supportsAdvice(advice)) { interceptors.add(adapter.getInterceptor(advisor)); } } if(interceptors.isEmpty()) { throw new UnknownAdviceTypeException(advisor.getAdvice()); } else { return (MethodInterceptor[])interceptors.toArray(new MethodInterceptor[interceptors.size()]); } } public void registerAdvisorAdapter(AdvisorAdapter adapter) { this.adapters.add(adapter); } }













生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 美国人和狍xxxx视频 | 最近中文字幕大全高清在线 | 在线观看视频免费播放 | 正在播放国产露脸真实高清 | 成人18xxxx网站 | 国产成人一区二区三区视频免费 | 亚洲 欧美 日韩中文字幕一区二区 | 在线亚洲欧国产精品专区 | 一级特黄特黄毛片欧美的 | 亚洲人成777在线播放 | 久久亚洲精中文字幕冲田杏梨 | 伊人黄色片| 香蕉久久ac一区二区三区 | 中文字幕资源在线 | 国产精品免费一区二区区 | 3344成年站福利在线视频免费 | 日本综合欧美一区二区三区 | 男人看的网址 | 在线精品国产成人综合第一页 | jizzjizzjizz亚洲| 亚洲精品天堂 | 国产欧美一区二区三区免费 | 性欧美video另类3d | 国产精品国产精品国产专区不卡 | 69一级毛片| 粉嫩00福利视频在线精品 | 日本一级毛片免费播放 | 欧美 日韩 亚洲另类专区 | 91av综合| videos亚洲 | 欧美一区二区三区精品国产 | v片在线看 | 一区二区三区四区在线播放 | 国产第一页福利 | 人成免费a级毛片 | 欧美日韩中文字幕一区二区高清 | 国产成人精品久久综合 | a毛片a毛片a视频 | 欧美大胆色图 | 8av国产精品爽爽ⅴa在线观看 | 影音先锋色天使 |