前言:
现在朋友们对“aop代理对象在什么时候创建”都比较关怀,小伙伴们都需要剖析一些“aop代理对象在什么时候创建”的相关资讯。那么小编也在网摘上汇集了一些关于“aop代理对象在什么时候创建””的相关知识,希望看官们能喜欢,你们一起来了解一下吧!前言
Spring AOP 是 Spring 核心功能之一,日常的工作少不了和 AOP 打交道;是时候有必要去了解 Spring 对 AOP 创建代理其背后的原理,这样子我们才能写出更加高质量的代码及产生 BUG 的原因。
小编今天主要带大家了解 AOP 的一些概念,AOP 的实现方式有哪些,最主要还是介绍 Spring AOP 的创建代理和对象源码。
读者福利:转发+关注 私信【学习笔记】获取小编整理好的Java知识点学习笔记一份。
1、 工程简介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> <!-- 日志相关依赖 --> <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@Aspectpublic class DaoAopConfig { /** * 声明切点 */ @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@Aspectpublic class ServiceAopConfig { /** * 声明切点 */ @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
@Repositorypublic class StudentDao { public void addStudent() { System.out.println("StudentDao invoke addStudent"); }}1.4 Service
public interface StudentService { void addStudent();}@Servicepublic 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初始化时,后置加强。
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】获取当前bean有效的Advisor,Advisor = advice + pointCut */ Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); /** * 【2】创建代理对象 */ 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 创建代理对象源码解析3.1 createProxy
描述: 主流程调用方法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】创建代理工厂,赋值。 */ ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); /** * 【2】 proxyTargetClass为true时代表使用cglib,为false使用jdk,默认值是false。 * 判断当前被代理对象是使用jdk增强还是使用cglib增强 * */ if (!proxyFactory.isProxyTargetClass()) { //根据最开始@EnableAspectJAutoProxy注解中的proxyTargetClass参数判断是否应该使用cglib代理 if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { //如果是接口增强那么使用jdk,否则使用cglib evaluateProxyInterfaces(beanClass, proxyFactory); } } //构建advisor Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); //把advisor加入到代理工厂中 proxyFactory.addAdvisors(advisors); //把targetSource对象加入代理工厂(实际对象、被代理对象) proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } /** * 【3】 获取代理对象 */ return proxyFactory.getProxy(getProxyClassLoader()); }3.2 ProxyFactory 获取代理对象
描述: 先获取AOP代理
public Object getProxy(@Nullable ClassLoader classLoader) { /** * 创建AOP代理(JDK、CGLIB)并且获得代理对象 */ 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 根据AOP不同的代理获取代理对象4 StudentDao 代理Debug
描述: 每个代理对象都对应一个代理工厂,工厂是new 创建的。
描述: 选择cglib、jdk代理生成代理对象。
描述: 创建AOP代理。
描述: CglibAopProxy获取代理对象。
描述: 获取到cglib增强代理对象。
5 StudentServiceImpl 代理Debug
描述: StudentServiceImpl 实现StudentService接口使用jdk代理。
描述: AOP获取JDK代理。
描述: 获取代理对象。
原文链接:
标签: #aop代理对象在什么时候创建