- 浏览: 141360 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
西蜀石兰:
永远保持一颗好奇心,面对新鲜的事物时,乐意花代价去尝试一番,这 ...
优秀程序员必备的15大技能 -
liuwuhen:
代码还是不错的,头像确实有点
sprig AOP之ProxyFactory -
西蜀石兰:
这头像。。。。完全不用看代码了
sprig AOP之ProxyFactory -
coding1688:
...
你的知识资产 -
tao_gun:
...
你的知识资产
下面我们来看看Spring的AOP的一些相关代码是怎么得到Proxy的,让我们我们先看看AOP和Spring AOP的一些基本概念:
Advice:
通知,制定在连接点做什么,在Sping中,他主要描述Spring围绕方法调用注入的额外的行为,Spring提供的通知类型有:
before advice,AfterReturningAdvice,ThrowAdvice,MethodBeforeAdvice,这些都是Spring AOP定义的接口类,具体的动作实现需要用户程序来完成。
Pointcut:
切点,其决定一个advice应该应用于哪个连接点,也就是需要插入额外处理的地方的集合,例如,被某个advice作为目标的一组方法。Spring pointcut通常意味着标示方法,可以选择一组方法调用作为pointcut,Spring提供了具体的切点来给用户使用,比如正则表达式切点 JdkRegexpMethodPointcut通过正则表达式对方法名进行匹配,其通过使用 AbstractJdkRegexpMethodPointcut中的对MethodMatcher接口的实现来完成pointcut功能:
Java代码
public final boolean matches(Method method, Class targetClass) {
//这里通过放射得到方法的全名
String patt = method.getDeclaringClass().getName() + "." + method.getName();
for (int i = 0; i < this.patterns.length; i++) {
// 这里是判断是否和方法名是否匹配的代码
boolean matched = matches(patt, i);
if (matched) {
for (int j = 0; j < this.excludedPatterns.length; j++) {
boolean excluded = matchesExclusion(patt, j);
if(excluded) {
return false;
}
}
return true;
}
}
return false;
}
public final boolean matches(Method method, Class targetClass) {
//这里通过放射得到方法的全名
String patt = method.getDeclaringClass().getName() + "." + method.getName();
for (int i = 0; i < this.patterns.length; i++) {
// 这里是判断是否和方法名是否匹配的代码
boolean matched = matches(patt, i);
if (matched) {
for (int j = 0; j < this.excludedPatterns.length; j++) {
boolean excluded = matchesExclusion(patt, j);
if(excluded) {
return false;
}
}
return true;
}
}
return false;
}
在JDKRegexpMethodPointcut中通过JDK中的正则表达式匹配来完成pointcut的最终确定:
Java代码
protected boolean matches(String pattern, int patternIndex) {
Matcher matcher = this.compiledPatterns[patternIndex].matcher(pattern);
return matcher.matches();
}
protected boolean matches(String pattern, int patternIndex) {
Matcher matcher = this.compiledPatterns[patternIndex].matcher(pattern);
return matcher.matches();
}
Advisor:
当我们完成额外的动作设计(advice)和额外动作插入点的设计(pointcut)以后,我们需要一个对象把他们结合起来,这就是通知器 - advisor,定义应该在哪里应用哪个通知。Advisor的实现有:DefaultPointcutAdvisor他有两个属性advice和 pointcut来让我们配置advice和pointcut。
在ProxyFactoryBean 中,它的AOP实现需要依赖JDK和GCLIB提供的Proxy特性,从FcatoryBean中获取对象,是用getObject()方法作为入口完成,让我们进入ProxyFactoryBean中获取对象,是用getObject()方法作为入口完成的;让我们进入ProxyFactoryBean的实现中去,这个我们一点也不陌生的getObject()方法,是FactoryBean需要实现的接口。对ProxyFactoryBean来说,把需要对target目标对象增加的增强处理 ,都通过getObject的实现代码
//获取对象
public Object getObject()
throws BeansException
{
//初始化通知其链
initializeAdvisorChain();
if(isSingleton())
//返回单例对象
return getSingletonInstance();
if(targetName == null)
logger.warn("Using non-singleton proxies with singleton targets is often undesirable. Enable prototype proxies by setting the 'targetName' property.");
return newPrototypeInstance();
}
//对Advisor配置链的初始化
private synchronized void initializeAdvisorChain()
throws AopConfigException, BeansException
{
if(advisorChainInitialized)
return;
if(!ObjectUtils.isEmpty(interceptorNames))
{
if(beanFactory == null)
throw new IllegalStateException((new StringBuilder("No BeanFactory available anymore (probably due to serialization) - cannot resolve interceptor names ")).append(Arrays.asList(interceptorNames)).toString());
if(interceptorNames[interceptorNames.length - 1].endsWith("*") && targetName == null && targetSource == EMPTY_TARGET_SOURCE)
throw new AopConfigException("Target required after globals");
String as[];
int j = (as = interceptorNames).length;
for(int i = 0; i < j; i++)
{
String name = as[i];
if(logger.isTraceEnabled())
logger.trace((new StringBuilder("Configuring advisor or advice '")).append(name).append("'").toString());
if(name.endsWith("*"))
{
if(!(beanFactory instanceof ListableBeanFactory))
throw new AopConfigException("Can only use global advisors or interceptors with a ListableBeanFactory");
addGlobalAdvisor((ListableBeanFactory)beanFactory, name.substring(0, name.length() - "*".length()));
} else
{
Object advice;
if(singleton || beanFactory.isSingleton(name))
advice = beanFactory.getBean(name);
else
advice = new PrototypePlaceholderAdvisor(name);
addAdvisorOnChainCreation(advice, name);
}
}
}
advisorChainInitialized = true;
}
如果是生成singleton对象则在getSingleton中完成
private synchronized Object getSingletonInstance()
{
if(singletonInstance == null)
{
targetSource = freshTargetSource();
if(autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass())
{
Class targetClass = getTargetClass();
if(targetClass == null)
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
//设置代理接口
setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, proxyClassLoader));
}
super.setFrozen(freezeProxy);
singletonInstance = getProxy(createAopProxy());
}
return singletonInstance;
}
这里出现了AopProxy类型的对象是spring把AOP代理对象的实现与框架的其他部分有效的分离开,AopProxy是一个接口,它有两个子类实现
一个Cglib2AopProxy和JdkDynamicAopProxy,spring 是通过CGLIB和JDK来生成需要的Proxy代理对象。
在ProxyCreatorSupport 中的 createAopProxy()方法
protected final synchronized AopProxy createAopProxy()
{
if(!active)
activate();
return getAopProxyFactory().createAopProxy(this);
}
在 DefaultAopProxyFactory 中的 createAopProxy()是通过通过工厂来产生代理对象
public AopProxy createAopProxy(AdvisedSupport config)
throws AopConfigException
{
if(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))
{
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())
return new JdkDynamicAopProxy(config);
if(!cglibAvailable)
throw new AopConfigException("Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.");
else
//采用cglib方式产生代理对象
return CglibProxyFactory.createCglibProxy(config);
} else
{
//采用jdk动态代理产生代理对象
return new JdkDynamicAopProxy(config);
}
}
protected Object getProxy(AopProxy aopProxy)
{
return aopProxy.getProxy(proxyClassLoader);
}
如果是CGlib方式,则产生代理对象,则在Cglib2AopProxy中的getProxy方法其源码如下:
public Object getProxy(ClassLoader classLoader)
{
try
{
Class rootClass = advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class proxySuperClass = rootClass;
if(AopUtils.isCglibProxyClass(rootClass))
{
proxySuperClass = rootClass.getSuperclass();
Class additionalInterfaces[] = rootClass.getInterfaces();
Class aclass[];
int j = (aclass = additionalInterfaces).length;
for(int i = 0; i < j; i++)
{
Class additionalInterface = aclass[i];
advised.addInterface(additionalInterface);
}
}
validateClassIfNecessary(proxySuperClass);
Enhancer enhancer = createEnhancer();
if(classLoader != null)
{
enhancer.setClassLoader(classLoader);
if((classLoader instanceof SmartClassLoader) && ((SmartClassLoader)classLoader).isClassReloadable(proxySuperClass))
enhancer.setUseCache(false);
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setStrategy(new UndeclaredThrowableStrategy(java/lang/reflect/UndeclaredThrowableException));
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(advised));
enhancer.setInterceptDuringConstruction(false);
Callback callbacks[] = getCallbacks(rootClass);
enhancer.setCallbacks(callbacks);
enhancer.setCallbackFilter(new ProxyCallbackFilter(advised.getConfigurationOnlyCopy(), fixedInterceptorMap, fixedInterceptorOffset));
Class types[] = new Class[callbacks.length];
for(int x = 0; x < types.length; x++)
types[x] = callbacks[x].getClass();
enhancer.setCallbackTypes(types);
Object proxy;
if(constructorArgs != null)
proxy = enhancer.create(constructorArgTypes, constructorArgs);
else
proxy = enhancer.create();
return proxy;
}
catch(Exception ex)
{
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
我们在来看下JdkDynamicAopProxy 实现了InvokeHandle和Aopproxy接口jdk的代理方式。
public Object getProxy(ClassLoader classLoader)
{
if(logger.isDebugEnabled())
logger.debug((new StringBuilder("Creating JDK dynamic proxy: target source is ")).append(advised.getTargetSource()).toString());
Class proxiedInterfaces[] = AopProxyUtils.completeProxiedInterfaces(advised);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//这是jdk的代理方式,将执行invoke方法
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
这样用Proxy包装target之后,通过ProxyFactoryBean得到对其方法的调用就被Proxy拦截了, ProxyFactoryBean的getObject()方法得到的实际上是一个Proxy了,我们的target对象已经被封装了。对 ProxyFactoryBean这个工厂bean而言,其生产出来的对象是封装了目标对象的代理对象。
Advice:
通知,制定在连接点做什么,在Sping中,他主要描述Spring围绕方法调用注入的额外的行为,Spring提供的通知类型有:
before advice,AfterReturningAdvice,ThrowAdvice,MethodBeforeAdvice,这些都是Spring AOP定义的接口类,具体的动作实现需要用户程序来完成。
Pointcut:
切点,其决定一个advice应该应用于哪个连接点,也就是需要插入额外处理的地方的集合,例如,被某个advice作为目标的一组方法。Spring pointcut通常意味着标示方法,可以选择一组方法调用作为pointcut,Spring提供了具体的切点来给用户使用,比如正则表达式切点 JdkRegexpMethodPointcut通过正则表达式对方法名进行匹配,其通过使用 AbstractJdkRegexpMethodPointcut中的对MethodMatcher接口的实现来完成pointcut功能:
Java代码
public final boolean matches(Method method, Class targetClass) {
//这里通过放射得到方法的全名
String patt = method.getDeclaringClass().getName() + "." + method.getName();
for (int i = 0; i < this.patterns.length; i++) {
// 这里是判断是否和方法名是否匹配的代码
boolean matched = matches(patt, i);
if (matched) {
for (int j = 0; j < this.excludedPatterns.length; j++) {
boolean excluded = matchesExclusion(patt, j);
if(excluded) {
return false;
}
}
return true;
}
}
return false;
}
public final boolean matches(Method method, Class targetClass) {
//这里通过放射得到方法的全名
String patt = method.getDeclaringClass().getName() + "." + method.getName();
for (int i = 0; i < this.patterns.length; i++) {
// 这里是判断是否和方法名是否匹配的代码
boolean matched = matches(patt, i);
if (matched) {
for (int j = 0; j < this.excludedPatterns.length; j++) {
boolean excluded = matchesExclusion(patt, j);
if(excluded) {
return false;
}
}
return true;
}
}
return false;
}
在JDKRegexpMethodPointcut中通过JDK中的正则表达式匹配来完成pointcut的最终确定:
Java代码
protected boolean matches(String pattern, int patternIndex) {
Matcher matcher = this.compiledPatterns[patternIndex].matcher(pattern);
return matcher.matches();
}
protected boolean matches(String pattern, int patternIndex) {
Matcher matcher = this.compiledPatterns[patternIndex].matcher(pattern);
return matcher.matches();
}
Advisor:
当我们完成额外的动作设计(advice)和额外动作插入点的设计(pointcut)以后,我们需要一个对象把他们结合起来,这就是通知器 - advisor,定义应该在哪里应用哪个通知。Advisor的实现有:DefaultPointcutAdvisor他有两个属性advice和 pointcut来让我们配置advice和pointcut。
在ProxyFactoryBean 中,它的AOP实现需要依赖JDK和GCLIB提供的Proxy特性,从FcatoryBean中获取对象,是用getObject()方法作为入口完成,让我们进入ProxyFactoryBean中获取对象,是用getObject()方法作为入口完成的;让我们进入ProxyFactoryBean的实现中去,这个我们一点也不陌生的getObject()方法,是FactoryBean需要实现的接口。对ProxyFactoryBean来说,把需要对target目标对象增加的增强处理 ,都通过getObject的实现代码
//获取对象
public Object getObject()
throws BeansException
{
//初始化通知其链
initializeAdvisorChain();
if(isSingleton())
//返回单例对象
return getSingletonInstance();
if(targetName == null)
logger.warn("Using non-singleton proxies with singleton targets is often undesirable. Enable prototype proxies by setting the 'targetName' property.");
return newPrototypeInstance();
}
//对Advisor配置链的初始化
private synchronized void initializeAdvisorChain()
throws AopConfigException, BeansException
{
if(advisorChainInitialized)
return;
if(!ObjectUtils.isEmpty(interceptorNames))
{
if(beanFactory == null)
throw new IllegalStateException((new StringBuilder("No BeanFactory available anymore (probably due to serialization) - cannot resolve interceptor names ")).append(Arrays.asList(interceptorNames)).toString());
if(interceptorNames[interceptorNames.length - 1].endsWith("*") && targetName == null && targetSource == EMPTY_TARGET_SOURCE)
throw new AopConfigException("Target required after globals");
String as[];
int j = (as = interceptorNames).length;
for(int i = 0; i < j; i++)
{
String name = as[i];
if(logger.isTraceEnabled())
logger.trace((new StringBuilder("Configuring advisor or advice '")).append(name).append("'").toString());
if(name.endsWith("*"))
{
if(!(beanFactory instanceof ListableBeanFactory))
throw new AopConfigException("Can only use global advisors or interceptors with a ListableBeanFactory");
addGlobalAdvisor((ListableBeanFactory)beanFactory, name.substring(0, name.length() - "*".length()));
} else
{
Object advice;
if(singleton || beanFactory.isSingleton(name))
advice = beanFactory.getBean(name);
else
advice = new PrototypePlaceholderAdvisor(name);
addAdvisorOnChainCreation(advice, name);
}
}
}
advisorChainInitialized = true;
}
如果是生成singleton对象则在getSingleton中完成
private synchronized Object getSingletonInstance()
{
if(singletonInstance == null)
{
targetSource = freshTargetSource();
if(autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass())
{
Class targetClass = getTargetClass();
if(targetClass == null)
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
//设置代理接口
setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, proxyClassLoader));
}
super.setFrozen(freezeProxy);
singletonInstance = getProxy(createAopProxy());
}
return singletonInstance;
}
这里出现了AopProxy类型的对象是spring把AOP代理对象的实现与框架的其他部分有效的分离开,AopProxy是一个接口,它有两个子类实现
一个Cglib2AopProxy和JdkDynamicAopProxy,spring 是通过CGLIB和JDK来生成需要的Proxy代理对象。
在ProxyCreatorSupport 中的 createAopProxy()方法
protected final synchronized AopProxy createAopProxy()
{
if(!active)
activate();
return getAopProxyFactory().createAopProxy(this);
}
在 DefaultAopProxyFactory 中的 createAopProxy()是通过通过工厂来产生代理对象
public AopProxy createAopProxy(AdvisedSupport config)
throws AopConfigException
{
if(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))
{
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())
return new JdkDynamicAopProxy(config);
if(!cglibAvailable)
throw new AopConfigException("Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.");
else
//采用cglib方式产生代理对象
return CglibProxyFactory.createCglibProxy(config);
} else
{
//采用jdk动态代理产生代理对象
return new JdkDynamicAopProxy(config);
}
}
protected Object getProxy(AopProxy aopProxy)
{
return aopProxy.getProxy(proxyClassLoader);
}
如果是CGlib方式,则产生代理对象,则在Cglib2AopProxy中的getProxy方法其源码如下:
public Object getProxy(ClassLoader classLoader)
{
try
{
Class rootClass = advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class proxySuperClass = rootClass;
if(AopUtils.isCglibProxyClass(rootClass))
{
proxySuperClass = rootClass.getSuperclass();
Class additionalInterfaces[] = rootClass.getInterfaces();
Class aclass[];
int j = (aclass = additionalInterfaces).length;
for(int i = 0; i < j; i++)
{
Class additionalInterface = aclass[i];
advised.addInterface(additionalInterface);
}
}
validateClassIfNecessary(proxySuperClass);
Enhancer enhancer = createEnhancer();
if(classLoader != null)
{
enhancer.setClassLoader(classLoader);
if((classLoader instanceof SmartClassLoader) && ((SmartClassLoader)classLoader).isClassReloadable(proxySuperClass))
enhancer.setUseCache(false);
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setStrategy(new UndeclaredThrowableStrategy(java/lang/reflect/UndeclaredThrowableException));
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(advised));
enhancer.setInterceptDuringConstruction(false);
Callback callbacks[] = getCallbacks(rootClass);
enhancer.setCallbacks(callbacks);
enhancer.setCallbackFilter(new ProxyCallbackFilter(advised.getConfigurationOnlyCopy(), fixedInterceptorMap, fixedInterceptorOffset));
Class types[] = new Class[callbacks.length];
for(int x = 0; x < types.length; x++)
types[x] = callbacks[x].getClass();
enhancer.setCallbackTypes(types);
Object proxy;
if(constructorArgs != null)
proxy = enhancer.create(constructorArgTypes, constructorArgs);
else
proxy = enhancer.create();
return proxy;
}
catch(Exception ex)
{
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
我们在来看下JdkDynamicAopProxy 实现了InvokeHandle和Aopproxy接口jdk的代理方式。
public Object getProxy(ClassLoader classLoader)
{
if(logger.isDebugEnabled())
logger.debug((new StringBuilder("Creating JDK dynamic proxy: target source is ")).append(advised.getTargetSource()).toString());
Class proxiedInterfaces[] = AopProxyUtils.completeProxiedInterfaces(advised);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//这是jdk的代理方式,将执行invoke方法
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
这样用Proxy包装target之后,通过ProxyFactoryBean得到对其方法的调用就被Proxy拦截了, ProxyFactoryBean的getObject()方法得到的实际上是一个Proxy了,我们的target对象已经被封装了。对 ProxyFactoryBean这个工厂bean而言,其生产出来的对象是封装了目标对象的代理对象。
发表评论
-
spring 事务
2012-08-21 15:38 1011spring的事务是从TransactionProxyFact ... -
sprig AOP之ProxyFactory
2012-08-20 18:34 3738我们在项目中大多使用的声明式的AOP配置,其实在spring中 ... -
spring AOP源码分析之拦截器
2012-08-20 17:09 1413我们都知道在spring AOP中产生代理对象的方式有jdk和 ... -
spring jdbc 之一
2012-08-16 15:16 1411使用过jdbc的我们都知道spring jdbc ,首先我们看 ... -
spring jdbc 之二
2012-08-15 16:12 1568spring jdbcTemplate 提供了很多查询和更新功 ...
相关推荐
本文将深入探讨如何在Spring中通过自定义工具类获取代理对象所代理的目标对象。 ### 核心概念:AOP与Spring Proxy 在理解如何获取目标对象之前,我们需要先了解Spring AOP的实现机制。Spring AOP主要通过动态代理...
`ProxyFactoryBean`是Spring AOP实现中的一个重要类,它用于创建代理对象,使我们能够实现动态代理以进行方法拦截。下面将深入分析`ProxyFactoryBean`的源码,探讨其工作原理和使用方式。 `ProxyFactoryBean`继承自...
AnnotationAwareAspectJAutoProxyCreator类是Spring AOP用来创建代理对象的核心组件之一。它通过扫描类上标注了特定AOP注解的类(如@Aspect)并根据这些信息来创建代理对象。当容器中的bean需要创建时,...
当我们通过Spring容器获取一个bean时,实际上是获取了它的代理对象。代理对象在调用目标方法前后,会根据通知类型执行相应的逻辑。比如,如果定义了一个前置通知,那么在调用目标方法之前,前置通知会被执行。 6. ...
Spring AOP的源码分析主要涉及以下几个部分: - **ProxyFactoryBean**:它是Spring AOP代理的工厂类,负责创建代理对象。 - **Advised**:接口,代表可以配置通知的对象,如代理对象。 - **AopProxy**:接口,定义了...
Spring AOP是基于代理的,它提供了声明式的方式来实现AOP。 1. **切面(Aspect)**:切面是AOP的核心,它结合了关注点(例如,日志记录)和它们的实现。在Spring AOP中,一个切面通常是一个包含通知(advisors)和...
《Spring源码分析》 Spring框架作为Java领域中不可或缺的一部分,其强大之处在于它提供了丰富的功能,包括依赖注入(Dependency Injection,简称DI)、面向切面编程(Aspect-Oriented Programming,简称AOP)、事务...
### Spring5源码分析心得 #### 一、Spring框架中常用的设计模式 Spring框架作为一款优秀的Java企业级应用开发框架,其内部集成了多种设计模式,不仅有助于提高系统的可维护性和扩展性,还能够让开发者更好地理解和...
通过对这些模块的源码分析,我们可以深入了解Spring如何实现其强大的功能,并能更好地运用到实际项目中,提升代码质量和可维护性。无论是新手还是经验丰富的开发者,理解Spring的源码都将是一次宝贵的进阶之旅。
在源码分析中,理解`AopProxy`、`TargetSource`以及它们如何协同工作以创建代理对象是关键。此外,`AspectJ`扩展了Spring AOP,提供了更强大的表达式语言和编译时织入,对复杂切面需求的开发者非常有用。 综上所述...
《Spring源码分析——BeanFactory》 在Java的IoC(Inversion of Control)和DI(Dependency Injection)领域,Spring框架扮演着至关重要的角色。BeanFactory是Spring的核心组件之一,它是容器的基石,负责管理应用...
Spring 动态代理是 Spring 框架中的一个重要特性,它允许我们在运行时自动生成代理对象,以便在方法调用前后执行额外的操作,比如事务管理、AOP(面向切面编程)等。动态代理主要涉及两个核心接口:`java.lang....
源码分析是理解Spring工作原理的关键,能帮助开发者深入掌握如何在实际项目中有效地使用和优化Spring。下面将对Spring框架的核心组件、设计理念以及源码中的关键部分进行详细的解释。 1. **依赖注入(DI)** - ...
《Spring源码分析——ApplicationContext》 在Java世界中,Spring框架是不可或缺的一部分,它以其强大的IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)特性,极大地...
通过深入源码分析,我们可以更好地理解Spring如何在幕后工作,从而更有效地利用这个强大的框架来构建复杂的企业级应用。希望这篇文章能帮助你提升对Spring的理解,让你在实际开发中更加得心应手。
当你看到TransactionProxyFactoryBean时,实际上是在创建一个事务增强的代理对象。源码中可以学习到AOP代理的工作原理,以及如何通过拦截器链执行事务逻辑。 7. **数据访问对象(DAO)支持** Spring-ORM提供了对...
在源码分析中,我们可以看到当一个方法被@Transactional标记后,Spring会创建一个代理,这个代理在目标方法执行前后插入事务管理逻辑。在方法开始前,如果满足事务启动条件,就会调用`PlatformTransactionManager`的...
此外,Spring还支持基于接口的代理,例如,如果bean需要AOP代理,那么在从Map中获取bean之前,会先创建一个代理对象返回。 总的来说,Spring通过Bean Factory中的Map来管理和提供bean实例,这个机制使得对象的创建...
而动态代理则在`spring-aop`模块中体现,如`JdkDynamicAopProxy`和`CglibAopProxy`用于创建代理对象。 另外,Spring的事件驱动模型(Event-driven model)和资源加载机制也是源码学习的重要部分。`ApplicationEvent...
在本文中,我们将深入探讨Spring AOP的底层实现,特别是围绕`@EnableAspectJAutoProxy`注解和`AnnotationAwareAspectJAutoProxyCreator`组件的源码分析。 一、@EnableAspectJAutoProxy是什么? `@...