<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring AOP創(chuàng)建代理對(duì)象源碼解析

          共 14898字,需瀏覽 30分鐘

           ·

          2021-04-03 21:26

          公眾號(hào)關(guān)注 “GitHub今日熱榜
          設(shè)為 “星標(biāo)”,帶你挖掘更多開發(fā)神器!






          1 工程簡(jiǎn)介



          1.1 pom


          <properties>
                  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                  <maven.compiler.source>1.8</maven.compiler.source>
                  <maven.compiler.target>1.8</maven.compiler.target>
                  <spring.version>5.2.8.RELEASE</spring.version>
              </properties>

              <dependencies>
                  <dependency>
                      <groupId>junit</groupId>
                      <artifactId>junit</artifactId>
                      <version>4.13</version>
                  </dependency>
                  <dependency>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-context</artifactId>
                      <version>${spring.version}</version>
                  </dependency>
                  <dependency>
                      <groupId>org.projectlombok</groupId>
                      <artifactId>lombok</artifactId>
                      <version>1.16.20</version>
                  </dependency>
                  <!-- 日志相關(guān)依賴 -->
                  <dependency>
                      <groupId>org.slf4j</groupId>
                      <artifactId>slf4j-api</artifactId>
                      <version>1.7.10</version>
                  </dependency>
                  <dependency>
                      <groupId>ch.qos.logback</groupId>
                      <artifactId>logback-classic</artifactId>
                      <version>1.1.2</version>
                  </dependency>
                  <dependency>
                      <groupId>ch.qos.logback</groupId>
                      <artifactId>logback-core</artifactId>
                      <version>1.1.2</version>
                  </dependency>

                  <dependency>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-aspects</artifactId>
                      <version>${spring.version}</version>
                  </dependency>
              </dependencies>


          1.2 AOP配置文件


          @Configuration
          @EnableAspectJAutoProxy
          @Import({ServiceAopConfig.class, DaoAopConfig.class})
          public class AopConfig {


          }

          @Configuration
          @Aspect
          public class DaoAopConfig {

              /**
               * 聲明切點(diǎn)
               */

              @Pointcut("execution(* com.rosh.dao.*.*(..))")
              public void pointCut() {

              }

              @Around("pointCut()")
              public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
                  System.out.println("DaoAopConfig invoke around start");
                  Object proceed = proceedingJoinPoint.proceed();
                  System.out.println("DaoAopConfig invoke around end");
                  return proceed;
              }
          }



          @Configuration
          @Aspect
          public class ServiceAopConfig {

              /**
               * 聲明切點(diǎn)
               */

              @Pointcut("execution(* com.rosh.service.*.*(..))")
              public void pointCut() {

              }

              @Around("pointCut()")
              public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
                  System.out.println("ServiceAopConfig invoke around start");
                  Object proceed = proceedingJoinPoint.proceed();
                  System.out.println("ServiceAopConfig invoke around end");
                  return proceed;
              }

              @Before("pointCut()")
              public void before(){
                  System.out.println("ServiceAopConfig invoke before");
              }

              @After("pointCut()")
              public void after() {
                  System.out.println("ServiceAopConfig invoke after");
              }
          }


          1.3 StudentDao


          @Repository
          public class StudentDao {

              public void addStudent() {

                  System.out.println("StudentDao invoke addStudent");

              }

          }


          1.4 Service


          public interface StudentService {

               void addStudent();

          }


          @Service
          public class StudentServiceImpl implements StudentService {

              @Override
              public void addStudent() {
                  System.out.println("StudentServiceImpl invoke addStudent()");
              }
          }


          1.5 RoshTest


          public class RoshTest {

              @Test
              public void mainTest()
          {

                  AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext("com.rosh");
                  StudentService studentService = (StudentService) applicationContext.getBean("studentServiceImpl");
                  studentService.addStudent();

                  System.out.println("===============分割線================");

                  StudentDao studentDao=(StudentDao) applicationContext.getBean("studentDao");
                  studentDao.addStudent();


              }

          }



          2 AbstractAutoProxyCreator概述


          描述:該類作用在,Spring Aop初始化源碼分析中具體分析過,核心作用是,在bean初始化時(shí),后置加強(qiáng)。




          protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
              if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
                return bean;
              }
              if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
                return bean;
              }
              if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
              }

              // Create proxy if we have advice.
              /**
               * 【1】獲取當(dāng)前bean有效的Advisor,Advisor = advice + pointCut
               */

              Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

              if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);

                /**
                 * 【2】創(chuàng)建代理對(duì)象
                 */

                Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
              }

              this.advisedBeans.put(cacheKey, Boolean.FALSE);
              return bean;
            }


          3 創(chuàng)建代理對(duì)象源碼解析


          3.1 createProxy


          描述:主流程調(diào)用方法AbstractAutoProxyCreator類createProxy 方法。


          protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
                @Nullable Object[] specificInterceptors, TargetSource targetSource) {

              if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
                AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
              }

              /**
               * 【1】創(chuàng)建代理工廠,賦值。
               */

              ProxyFactory proxyFactory = new ProxyFactory();
              proxyFactory.copyFrom(this);

              /**
               * 【2】 proxyTargetClass為true時(shí)代表使用cglib,為false使用jdk,默認(rèn)值是false。
               * 判斷當(dāng)前被代理對(duì)象是使用jdk增強(qiáng)還是使用cglib增強(qiáng)
               *
               */

              if (!proxyFactory.isProxyTargetClass()) {
                //根據(jù)最開始@EnableAspectJAutoProxy注解中的proxyTargetClass參數(shù)判斷是否應(yīng)該使用cglib代理
                if (shouldProxyTargetClass(beanClass, beanName)) {
                  proxyFactory.setProxyTargetClass(true);
                }
                else {
                  //如果是接口增強(qiáng)那么使用jdk,否則使用cglib
                  evaluateProxyInterfaces(beanClass, proxyFactory);
                }
              }
              //構(gòu)建advisor
              Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
              //把a(bǔ)dvisor加入到代理工廠中
              proxyFactory.addAdvisors(advisors);
              //把targetSource對(duì)象加入代理工廠(實(shí)際對(duì)象、被代理對(duì)象)
              proxyFactory.setTargetSource(targetSource);
              customizeProxyFactory(proxyFactory);

              proxyFactory.setFrozen(this.freezeProxy);
              if (advisorsPreFiltered()) {
                proxyFactory.setPreFiltered(true);
              }

              /**
               * 【3】 獲取代理對(duì)象
               */

              return proxyFactory.getProxy(getProxyClassLoader());
            }


          3.2 ProxyFactory 獲取代理對(duì)象


          描述:先獲取AOP代理


          public Object getProxy(@Nullable ClassLoader classLoader) {
              /**
               * 創(chuàng)建AOP代理(JDK、CGLIB)并且獲得代理對(duì)象
               */

              return createAopProxy().getProxy(classLoader);
            }


          protected final synchronized AopProxy createAopProxy() {
              if (!this.active) {
                activate();
              }
              return getAopProxyFactory().createAopProxy(this);
            }


          @Override
            public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
              if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {

                // 如果targetClass是接口類,使用JDK來生成Proxy
                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.");
                }
                if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                  return new JdkDynamicAopProxy(config);
                }

                // 如果不是接口類,使用CGLIB生成Proxy
                return new ObjenesisCglibAopProxy(config);
              }
              else {
                return new JdkDynamicAopProxy(config);
              }
            }


          3.3 根據(jù)AOP不同的代理獲取代理對(duì)象




          4 StudentDao 代理Debug


          描述:每個(gè)代理對(duì)象都對(duì)應(yīng)一個(gè)代理工廠,工廠是new 創(chuàng)建的。



          描述:選擇cglib、jdk代理生成代理對(duì)象。





          描述:創(chuàng)建AOP代理。



          描述:CglibAopProxy獲取代理對(duì)象。



          描述:獲取到cglib增強(qiáng)代理對(duì)象。



          5 StudentServiceImpl 代理Debug


          描述:StudentServiceImpl 實(shí)現(xiàn)StudentService接口使用jdk代理。



          描述:AOP獲取JDK代理。



          描述:獲取代理對(duì)象。






          出處:https://blog.csdn.net/qq_34125999/article/details/115107521









          關(guān)注GitHub今日熱榜,專注挖掘好用的開發(fā)工具,致力于分享優(yōu)質(zhì)高效的工具、資源、插件等,助力開發(fā)者成長(zhǎng)!







          點(diǎn)個(gè)在看 你最好看



          瀏覽 119
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  暗呦网一区二区三区 | 日韩精品一级毛片 | 亚洲综合免费观看高清 | 美女操逼逼网站 | 小骚逼黄色大片 |