`

spring-aop-ProxyFactoryBean 源码分析

阅读更多
在阅读本篇之前,请先阅读http://wangxinchun.iteye.com/blog/2079024,重复的逻辑,本篇不再进行分析~
在spring框架有一个鲜明的特点,一般的服务 都有编程式的和配置式的两种实现。
编程方式的使用往往比较明了,但是功能相对弱,使用不够简洁。配置式的往往能结合spring的ioc框架,提供更松散更强大的功能,兼容并蓄在spring框架在所有方面都表现的淋漓尽致。

相对于ProxyFactory 实现AOP拦截的方式,ProxyFactoryBean  是通过配置实现所有拦截功能。

使用case:
业务类
public interface LoginService {
	public boolean login(User user);
}
public class LoginServiceImpl implements LoginService {
	public boolean login(User user) {
		System.out.println(user);
		if (user == null) {
			return false;
		} else if (user.getUsername() == "xinchun.wang" && user.getPassword() == "123456") {
			return true;
		}
		return false;
	}
}

增强(Advice,Interceptor)
public class AfterAdvice1 implements AfterReturningAdvice{
	public void afterReturning(Object returnValue, Method method,
			Object[] args, Object target) throws Throwable {
		System.out.println("AfterAdvice1.afterReturning() execute ");
	}
}
public class AfterAdvice2 implements AfterReturningAdvice{
	public void afterReturning(Object returnValue, Method method,
			Object[] args, Object target) throws Throwable {
		System.out.println("AfterAdvice2.afterReturning() execute ");
	}
}

public class BeforeAdvice1 implements MethodBeforeAdvice{
	public void before(Method method, Object[] args, Object target)
			throws Throwable {
		System.out.println("BeforeAdvice1.before() execute ");
	}
}
public class BeforeAdvice2 implements MethodBeforeAdvice{
	public void before(Method method, Object[] args, Object target)
			throws Throwable {
		System.out.println("BeforeAdvice2.before() execute ");
	}
}

其他辅助工具代码:
public class BeanFactoryUtils implements BeanFactoryAware{
	private static BeanFactory beanFactory;
	public static BeanFactoryUtils getInstance(){
		return (BeanFactoryUtils)beanFactory.getBean("factoryUtil");
	}
	public void setBeanFactory(BeanFactory bf) throws BeansException {
        beanFactory = bf;		
	}
	public BeanFactory getBeanFactory() {
		return beanFactory;
	}
}


applicationContext.xml 配置
<bean id="afterAdvice1" class="com.qunar.service.AfterAdvice1" />
	<bean id="afterAdvice2" class="com.qunar.service.AfterAdvice2" />
	<bean id="beforeAdvice1" class="com.qunar.service.BeforeAdvice1" />
	<bean id="beforeAdvice2" class="com.qunar.service.BeforeAdvice1" />
<bean id="loginService" class="com.qunar.service.LoginServiceImpl"/>
	<bean id="factoryUtil" class=" com.qunar.util.BeanFactoryUtils" />
	<bean id="loginServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<!--这里代理的是接口 -->
		<property name="proxyInterfaces">
			<value> com.qunar.service.LoginService</value>
		</property>
		<!--是ProxyFactoryBean要代理的目标类 -->
		<property name="target">
			<ref bean="loginService" />
		</property>
		<!--程序中的Advice -->
		<property name="interceptorNames">
			<list>
				<value>afterAdvice1</value>
				<value>afterAdvice2</value>
				<value>beforeAdvice1</value>
				<value>beforeAdvice2</value>
			</list>
		</property>
	</bean>


测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:META-INF/spring/applicationContext.xml"})
public class LoginServiceImplTest {
	@Test
	public void proxyLoginTest() {
		LoginService loginService = (LoginService)BeanFactoryUtils.getInstance().getBeanFactory().getBean("loginServiceProxy");
		loginService.login(new User("xinchun.wang","123456"));
	}
}


输出:
BeforeAdvice1.before() execute
BeforeAdvice1.before() execute
com.qunar.vo.User@111b910
AfterAdvice2.afterReturning() execute
AfterAdvice1.afterReturning() execute

概述:
ProxyFactoryBean 在继承体系上和ProxyFactory并没有太多差异,但是ProxyFactoryBean实现了 BeanFactoryAware BeanClassLoaderAware FactoryBean 三个接口,熟悉IOC容器的话,可以知晓ProxyFactoryBean 和IOC容器有了交融的地方了,ProxyFactoryBean 正是借助IOC容器的配置,找到Advice增强和target对象。
下面进入源码剖析
public class ProxyFactoryBean extends ProxyCreatorSupport
		implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {

	/**
	 * interceptor 名字的通配符
	 */
	public static final String GLOBAL_SUFFIX = "*";

	protected final Log logger = LogFactory.getLog(getClass());
  //拦截器的名字
	private String[] interceptorNames;
	//代理对象的名字
	private String targetName;

	private boolean autodetectInterfaces = true;

	private boolean singleton = true;
	//这个类在ProxyFactory 已经说过了,可以参考下。是做拦截器的解析的。
	private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();

	private boolean freezeProxy = false;

	private transient ClassLoader proxyClassLoader = ClassUtils.getDefaultClassLoader();

	private transient boolean classLoaderConfigured = false;
  //IOC容器
	private transient BeanFactory beanFactory;

	/** Whether the advisor chain has already been initialized */
	private boolean advisorChainInitialized = false;

	/** 如果但是,singletonInstance 可以缓存  */
	private Object singletonInstance;


	/**
	 * 设置代理的接口,如果没有设置,那么会用cglib2做代理。
	 */
	public void setProxyInterfaces(Class[] proxyInterfaces) throws ClassNotFoundException {
		setInterfaces(proxyInterfaces);
	}

	/**
	  设置interceptorNames 拦截器的名字,但是这些名字必须在IOC容器里注册了。
	  interceptorNames 对应的名字的类型可以是 Interceptor, Advisor or Advice,
	  最后一项可以是IOC容器中的任何一个,如果他不是Advice 也不是 Advisor,会使用
	  SingletonTargetSource 进行包装这个对象,如果 target 或者 targetSource 或者targetName
	  设置了,那么 interceptorNames 只能包含 Advice/Advisor bean names.*/
	
	public void setInterceptorNames(String[] interceptorNames) {
		this.interceptorNames = interceptorNames;
	}

	/**
	 * 设置targetname
	 */
	public void setTargetName(String targetName) {
		this.targetName = targetName;
	}

	/**
	 * 设置是否自动检测接口,默认是true,如果为false,那么所有的借口都是cglib来代理。
	 */
	public void setAutodetectInterfaces(boolean autodetectInterfaces) {
		this.autodetectInterfaces = autodetectInterfaces;
	}

	/**
	 * 设置是否单件模式
	 */
	public void setSingleton(boolean singleton) {
		this.singleton = singleton;
	}

	/**
	 *you know。。。
	 */
	public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {
		this.advisorAdapterRegistry = advisorAdapterRegistry;
	}

	@Override
	public void setFrozen(boolean frozen) {
		this.freezeProxy = frozen;
	}

	
	public void setProxyClassLoader(ClassLoader classLoader) {
		this.proxyClassLoader = classLoader;
		this.classLoaderConfigured = (classLoader != null);
	}

	public void setBeanClassLoader(ClassLoader classLoader) {
		if (!this.classLoaderConfigured) {
			this.proxyClassLoader = classLoader;
		}
	}
  //拥有了beanfacotry的能力了。
	public void setBeanFactory(BeanFactory beanFactory) {
		this.beanFactory = beanFactory;
		checkInterceptorNames();
	}


	/**
	 * 对象获取的输入,深入分析此处!!!
	 */
	public Object getObject() throws BeansException {
		initializeAdvisorChain(); //第一次获取会初始化注册的advice 并进行包装 为Advisor
		if (isSingleton()) {
			return getSingletonInstance(); //如果是单例,返回代理对象
		}
		else {
			if (this.targetName == null) {
				logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
						"Enable prototype proxies by setting the 'targetName' property.");
			}
			return newPrototypeInstance(); //多例的情况
		}
	}


	public Class<?> getObjectType() {
		synchronized (this) {
			if (this.singletonInstance != null) {
				return this.singletonInstance.getClass();
			}
		}
		Class[] ifcs = getProxiedInterfaces();
		if (ifcs.length == 1) {
			return ifcs[0];
		}
		else if (ifcs.length > 1) {
			return createCompositeInterface(ifcs);
		}
		else if (this.targetName != null && this.beanFactory != null) {
			return this.beanFactory.getType(this.targetName);
		}
		else {
			return getTargetClass();
		}
	}

	public boolean isSingleton() {
		return this.singleton;
	}


	/**
	 *根据提供的接口列表,组装一个综合接口,实现所有的参数接口
	 */
	protected Class createCompositeInterface(Class[] interfaces) {
		return ClassUtils.createCompositeInterface(interfaces, this.proxyClassLoader);
	}

	/**
	 * 返回单例的代理对象
	 */
	private synchronized Object getSingletonInstance() {
		if (this.singletonInstance == null) { //如果第一次调用
			this.targetSource = freshTargetSource();
			if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
				// Rely on AOP infrastructure to tell us what interfaces to proxy.
				Class targetClass = getTargetClass();
				if (targetClass == null) {
					throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
				}
				setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
			}
			// Initialize the shared singleton instance.
			super.setFrozen(this.freezeProxy);
			this.singletonInstance = getProxy(createAopProxy()); //创建单例 createAopProxy 里使用 AopProxyFactory 根据当前配置创建aop代理(这块的细节参考ProxyFactory的讲解)
		}
		return this.singletonInstance;
	}

	  //返回一个新的代理对象
	private synchronized Object newPrototypeInstance() {
		if (logger.isTraceEnabled()) {
			logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this);
		}
  
    // copy 一份当前ProxyFacotryBean的配置 getAopProxyFactory 返回的工厂是可以复用的,他没有状态
		ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());
		// The copy needs a fresh advisor chain, and a fresh TargetSource.
		TargetSource targetSource = freshTargetSource();
		copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain()); //浅copy
		if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
			// Rely on AOP infrastructure to tell us what interfaces to proxy.
			copy.setInterfaces(
					ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));
		}
		copy.setFrozen(this.freezeProxy);

		if (logger.isTraceEnabled()) {
			logger.trace("Using ProxyCreatorSupport copy: " + copy);
		}
		return getProxy(copy.createAopProxy());
	}

	/**
	 * 返回一个代理对象 AopProxy 有jdk 和cglib两种实现
	 */
	protected Object getProxy(AopProxy aopProxy) {
		return aopProxy.getProxy(this.proxyClassLoader);
	}

	/**
	 * 检查处理interceptorNames 最后一个配置 是否是advice 或者advisor ,否则设置为target
	 */
	private void checkInterceptorNames() {
		if (!ObjectUtils.isEmpty(this.interceptorNames)) {
			String finalName = this.interceptorNames[this.interceptorNames.length - 1];
			if (this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
				//如果最后一个对象是设置的tareget实例
				if (!finalName.endsWith(GLOBAL_SUFFIX) && !isNamedBeanAnAdvisorOrAdvice(finalName)) {
					// finalName 不是拦截器
					this.targetName = finalName;
					if (logger.isDebugEnabled()) {
						logger.debug("Bean with name '" + finalName + "' concluding interceptor chain " +
								"is not an advisor class: treating it as a target or TargetSource");
					}
					String[] newNames = new String[this.interceptorNames.length - 1];
					System.arraycopy(this.interceptorNames, 0, newNames, 0, newNames.length);
					this.interceptorNames = newNames;
				}
			}
		}
	}

	/**
	 * 判断是否是Advisor 或者Advice
	 */
	private boolean isNamedBeanAnAdvisorOrAdvice(String beanName) {
		Class namedBeanClass = this.beanFactory.getType(beanName);
		if (namedBeanClass != null) {
			return (Advisor.class.isAssignableFrom(namedBeanClass) || Advice.class.isAssignableFrom(namedBeanClass));
		}
		// Treat it as an target bean if we can't tell.
		if (logger.isDebugEnabled()) {
			logger.debug("Could not determine type of bean with name '" + beanName +
					"' - assuming it is neither an Advisor nor an Advice");
		}
		return false;
	}

	
	private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
		if (this.advisorChainInitialized) {
			return;
		}

		if (!ObjectUtils.isEmpty(this.interceptorNames)) {
			if (this.beanFactory == null) {
				throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
						"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
			}

			// 如果指定了全局拦截器,那么必须显示指定targetSource 或者targetName
			if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
					this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
				throw new AopConfigException("Target required after globals");
			}

			for (String name : this.interceptorNames) {
				if (logger.isTraceEnabled()) {
					logger.trace("Configuring advisor or advice '" + name + "'");
				}

				if (name.endsWith(GLOBAL_SUFFIX)) { //如果匹配后缀*
					if (!(this.beanFactory instanceof ListableBeanFactory)) {
						throw new AopConfigException(
								"Can only use global advisors or interceptors with a ListableBeanFactory");
					}
					addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
							name.substring(0, name.length() - GLOBAL_SUFFIX.length())); //添加通配的advisor
				}

				else {
					// 
					Object advice;
					if (this.singleton || this.beanFactory.isSingleton(name)) {
						// 如果是单例,直接添加 Advisor/Advice to the chain.
						advice = this.beanFactory.getBean(name); 
					}
					else {
						//生成一个占位的advisor
						advice = new PrototypePlaceholderAdvisor(name);
					}
					addAdvisorOnChainCreation(advice, name);
				}
			}
		}

		this.advisorChainInitialized = true;
	}


	/**
	 * 返回独立的 advisor 列表,每次创建prototype 实例的时候,都要
	 */
	private List<Advisor> freshAdvisorChain() {
		Advisor[] advisors = getAdvisors();
		List<Advisor> freshAdvisors = new ArrayList<Advisor>(advisors.length);
		for (Advisor advisor : advisors) {
			if (advisor instanceof PrototypePlaceholderAdvisor) { //如果是占位advisor实例
				PrototypePlaceholderAdvisor pa = (PrototypePlaceholderAdvisor) advisor;
				if (logger.isDebugEnabled()) {
					logger.debug("Refreshing bean named '" + pa.getBeanName() + "'");
				}
				if (this.beanFactory == null) {
					throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
							"- cannot resolve prototype advisor '" + pa.getBeanName() + "'");
				}
				Object bean = this.beanFactory.getBean(pa.getBeanName());
				Advisor refreshedAdvisor = namedBeanToAdvisor(bean);
				freshAdvisors.add(refreshedAdvisor);
			}
			else {
				// Add the shared instance.
				freshAdvisors.add(advisor);
			}
		}
		return freshAdvisors;
	}

	/**
	  增加全局的通知器
	 */
	private void addGlobalAdvisor(ListableBeanFactory beanFactory, String prefix) {
		String[] globalAdvisorNames =
				BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Advisor.class); //找到所有Advisor
		String[] globalInterceptorNames =
				BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Interceptor.class); //找到所有Interceptor
		List<Object> beans = new ArrayList<Object>(globalAdvisorNames.length + globalInterceptorNames.length);
		Map<Object, String> names = new HashMap<Object, String>(beans.size());
		for (String name : globalAdvisorNames) {
			Object bean = beanFactory.getBean(name);
			beans.add(bean);
			names.put(bean, name);
		}
		for (String name : globalInterceptorNames) {
			Object bean = beanFactory.getBean(name);
			beans.add(bean);
			names.put(bean, name);
		}
		OrderComparator.sort(beans); 
		for (Object bean : beans) {
			String name = names.get(bean);
			if (name.startsWith(prefix)) {
				addAdvisorOnChainCreation(bean, name);
			}
		}
	}

	/**
	 * 当advice 创建的时候,增加Advice到拦截器列表
	 */
	private void addAdvisorOnChainCreation(Object next, String name) {
		Advisor advisor = namedBeanToAdvisor(next);
		if (logger.isTraceEnabled()) {
			logger.trace("Adding advisor with name '" + name + "'");
		}			
		addAdvisor(advisor);
	}
	
	private TargetSource freshTargetSource() {
		if (this.targetName == null) {
			if (logger.isTraceEnabled()) {
				logger.trace("Not refreshing target: Bean name not specified in 'interceptorNames'.");
			}
			return this.targetSource;
		}
		else {
			if (this.beanFactory == null) {
				throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
						"- cannot resolve target with name '" + this.targetName + "'");
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Refreshing target with name '" + this.targetName + "'");
			}
			Object target = this.beanFactory.getBean(this.targetName);
			return (target instanceof TargetSource ? (TargetSource) target : new SingletonTargetSource(target));
		}
	}

	/**
	 * Advisor or Advice转换为 Advisor
	 */
	private Advisor namedBeanToAdvisor(Object next) {
		try {
			return this.advisorAdapterRegistry.wrap(next);
		}
		catch (UnknownAdviceTypeException ex) {
			throw new AopConfigException("Unknown advisor type " + next.getClass() +
					"; Can only include Advisor or Advice type beans in interceptorNames chain except for last entry," +
					"which may also be target or TargetSource", ex);
		}
	}

	@Override
	protected void adviceChanged() {
		super.adviceChanged();
		if (this.singleton) {
			logger.debug("Advice has changed; recaching singleton instance");
			synchronized (this) {
				this.singletonInstance = null;
			}
		}
	}



	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
		// Rely on default serialization; just initialize state after deserialization.
		ois.defaultReadObject();

		// Initialize transient fields.
		this.proxyClassLoader = ClassUtils.getDefaultClassLoader();
	}


	/**
	 * Used in the interceptor chain where we need to replace a bean with a prototype
	 * on creating a proxy.
	 */
	private static class PrototypePlaceholderAdvisor implements Advisor, Serializable {

		private final String beanName;

		private final String message;
		
		public PrototypePlaceholderAdvisor(String beanName) {
			this.beanName = beanName;
			this.message = "Placeholder for prototype Advisor/Advice with bean name '" + beanName + "'";
		}
		
		public String getBeanName() {
			return beanName;
		}
		
		public Advice getAdvice() {
			throw new UnsupportedOperationException("Cannot invoke methods: " + this.message);
		}
		
		public boolean isPerInstance() {
			throw new UnsupportedOperationException("Cannot invoke methods: " + this.message);
		}
		
		@Override
		public String toString() {
			return this.message;
		}
	}

}
0
1
分享到:
评论

相关推荐

    spring-aop源码

    《深入剖析Spring AOP源码》 Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对现有代码进行功能增强的技术。本文将深入探讨Spring ...

    spring-aop AND proxy

    标题中的“spring-aop”指的是Spring框架中的面向切面编程(Aspect-Oriented Programming, AOP)模块,它...而阅读博主分享的源码分析和实践技巧,可以帮助我们更深入地理解这一技术,并将其有效地应用于实际项目中。

    spring-aop.rar

    《Spring AOP 深入理解与应用》 ...为了更好地理解Spring AOP的工作机制,可以阅读Spring AOP的源码,例如`org.springframework.aop.framework.ProxyFactoryBean`和`org.springframework.aop.aspectj.annotation....

    spring-aop.rar_aop1270_spring_spring aop

    本文将围绕Spring AOP的源码分析,探讨其核心概念、工作原理以及在实际开发中的应用。 一、AOP核心概念 1. 切面(Aspect):切面是关注点的模块化,通常包含一组通知(advises)和一个切入点(pointcut)定义。 2...

    五、Spring源码分析——Spring Aop

    《Spring AOP 源码分析》 在深入探讨Spring AOP之前,我们先要理解AOP(面向切面编程)的基本概念。AOP是一种编程范式,它将关注点分离,使得我们可以将横切关注点(如日志、事务管理、安全检查等)与业务逻辑解耦...

    官方原版源码 spring-5.2.8.RELEASE.zip

    首先,源码分析通常从项目结构开始。在解压后的文件中,我们看到有三个主要的子文件:`spring-5.2.8.RELEASE-dist.zip`、`spring-5.2.8.RELEASE-docs.zip`和`spring-5.2.8.RELEASE-schema.zip`。`spring-5.2.8....

    编译好的spring-framework-3.2.8.RELEASE源码

    《Spring框架3.2.8.RELEASE源码分析》 Spring框架是Java开发中的核心工具之一,它以其灵活、开放的架构以及强大的功能而闻名。3.2.8.RELEASE是Spring的一个稳定版本,提供了丰富的功能和改进。本文将深入探讨这个...

    spring-framework-5.2.0.RELEASE-master.zip

    在源码中,`org.springframework.aop`和`org.springframework.aop.framework`包下的类,如`AspectJExpressionPointcut`、`AdvisedSupport`和`ProxyFactoryBean`等,是用来实现AOP的关键。 **源码注释**: 这个...

    spring2-aop.pdf

    第三部分深入探讨了Spring框架的内部结构、设计原理以及项目源码分析。最后一部分则探讨了开源领域的相关话题,如开源框架设计的思考、开源社区的互动等。 本书还指出,通过EasyJF开源交流社区的论坛和SVN仓库可以...

    spring Aop文档

    #### 五、Spring AOP 的源码分析 Spring AOP的核心在于`Advisor`和`Advice`的实现,这些类通过`ProxyFactoryBean`或`CglibAopProxy`等代理工厂类生成代理对象。 1. **`Advisor`**:封装了`Pointcut`和`Advice`,是...

    spring-framework-5.3.29.tar.gz

    三、源码分析 深入Spring Framework 5.3.29的源码,我们可以看到它采用模块化设计,每个组件都有清晰的职责划分。例如,`org.springframework.beans`包主要处理Bean的创建和管理,`org.springframework.context`包...

    spring-framework-3.2.11官方源码

    通过对Spring Framework 3.2.11的源码分析,我们可以更深入地理解其设计思想,这对于提升开发技能、优化代码、解决实际问题都大有裨益。同时,源码阅读也能帮助我们跟踪和学习最新的框架发展动态,以便及时掌握Java...

    spring1.2.6源码

    通过阅读和分析Spring 1.2.6的源码,不仅可以学习到Spring的核心设计原则,还能了解到设计模式的运用,例如工厂模式、单例模式、观察者模式等。同时,这也是提升Java编程技巧和理解框架底层运作的好机会。在实际的...

    spring-framework-2.5.4源码.rar

    `org.springframework.aop`包包含了AOP的相关实现,如`AspectJ`的集成,`Pointcut`定义切点,`Advisor`定义通知,以及`ProxyFactoryBean`用于创建代理对象。 4. **数据访问集成**:Spring提供了对各种数据访问技术...

    spring 3.0 aop 实例

    6. **源码分析**:对于深入理解Spring AOP,阅读其源码是非常有帮助的。你可以通过查看`org.springframework.aop.framework.ProxyFactoryBean`和`org.springframework.aop.aspectj.annotation....

    spring-framework-4.1.0.RELEASE

    《Spring Framework 4.1.0.RELEASE:深入解析与源码分析》 Spring Framework作为Java开发中的核心框架,以其强大的功能和灵活的设计理念,深受广大开发者喜爱。本篇文章将聚焦于Spring Framework 4.1.0.RELEASE版本...

    spring-framework4.2x源码

    Spring Framework 4.2.x的源码分析,主要涉及以下几个核心模块: - **IoC(Inversion of Control)容器**:Spring的核心,负责管理对象的生命周期和依赖关系。通过XML、注解或Java配置实现,源码中可以研究...

    官方原版源码spring-framework-5.1.10.RELEASE.zip

    - 深入AOP模块,分析`ProxyFactoryBean`和`AspectJ`的相关代码。 - 分析`DispatcherServlet`和`HandlerMapping`,理解MVC的工作流程。 - 探索数据访问模块,研究不同数据源的适配器和操作。 通过阅读和理解Spring ...

    spring aop 学习笔记

    - `org.springframework.aop.framework.ProxyFactoryBean` 和 `org.springframework.aop.framework.JdkDynamicAopProxy` 是动态代理的关键类。 - `org.springframework.aop.aspectj.AspectJExpressionPointcut` ...

Global site tag (gtag.js) - Google Analytics