Spring源码分析-IOC之FactoryBeanRegistrySupport

       上一篇Spring源码分析-IOC之FactoryBean我们介绍了FactoryBean的使用,以及在ioc中的实现原理,其中实现原理中我们可以发现最终是调用的FactoryBeanRegistrySupport的getObjectFromFactoryBean和doGetObjectFromFactoryBean这个方法。

        FactoryBeanRegistrySupport主要是在DefaultSingletonBeanRegistry基础上增加了对FactoryBean的特殊处理功能,下面我们来看下具体的源码:

public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {

	//缓存factoryBeans创建的singletong对象
	private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(16);


	//获取指定factoryBean中实例化对象的类型
	protected Class<?> getTypeForFactoryBean(final FactoryBean<?> factoryBean) {
		try {
            //此处是JDK的权限控制,主要是操作系统层面的权限
            //我们开发中很少用到
			if (System.getSecurityManager() != null) {
				return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
					@Override
					public Class<?> run() {
						return factoryBean.getObjectType();
					}
				}, getAccessControlContext());
			}
			else {
				return factoryBean.getObjectType();
			}
		}
		catch (Throwable ex) {
			return null;
		}
	}

	//从缓存中获取指定的beanName的对象如果是NULL_OBJECT则返回null
	protected Object getCachedObjectForFactoryBean(String beanName) {
		Object object = this.factoryBeanObjectCache.get(beanName);
		return (object != NULL_OBJECT ? object : null);
	}

	//从指定的FactoryBean中获得给定beanName的实例对象
	protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
           //判断工厂是否是单例,以及单例缓存中是否有beanName
		if (factory.isSingleton() && containsSingleton(beanName)) {
            //单例缓存加上同步快防止并发
			synchronized (getSingletonMutex()) {
                //判断factoryBean中是否有指定的beanName
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {
                    //如果缓存中没有,通过factoryBean获取对象
					object = doGetObjectFromFactoryBean(factory, beanName);
					//再次从缓存中获取对象
                    //如果存在则赋值给object对象
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						object = alreadyThere;
					}
                    //不存在的话则获取,并存放到缓存池中
					else {
						if (object != null && shouldPostProcess) {
							try {
                                //此获取对象的方法一般有子类实现
								object = postProcessObjectFromFactoryBean(object, beanName);
							}
							catch (Throwable ex) {
								throw new BeanCreationException(beanName,
										"Post-processing of FactoryBean's singleton object failed", ex);
							}
						}
                           //将对象存放到缓存中
						this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
					}
				}
                //返回对象,如果是空对象的话则返回null
				return (object != NULL_OBJECT ? object : null);
			}
		}
		else {
            //通过factoryBean获取对象
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			if (object != null && shouldPostProcess) {
				try {
                     //此获取对象的方法一般有子类实现
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
				}
			}
            //返回对象
			return object;
		}
	}

	//通过factoryBean获取对象
	private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
			throws BeanCreationException {

		Object object;
		try {
               //此处是JDK的权限控制,主要是操作系统层面的权限
            //我们开发中很少用到
			if (System.getSecurityManager() != null) {
				AccessControlContext acc = getAccessControlContext();
				try {
					object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						@Override
						public Object run() throws Exception {
								return factory.getObject();
							}
						}, acc);
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
                //factoryBean直接获取对象,上一篇我们可以看到具体入口,怎么一步步进来
				object = factory.getObject();
			}
		}
		catch (FactoryBeanNotInitializedException ex) {
			throw new BeanCurrentlyInCreationException(beanName, ex.toString());
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
		}

		// 不允许对象为空,或者正在创建
		if (object == null && isSingletonCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(
					beanName, "FactoryBean which is currently in creation returned null from getObject");
		}
		return object;
	}

	//此方法一般由子类重写
	protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
		return object;
	}

	//获取指定名称的factoryBean,如果该实例是factoryBean的话,否则报错
	protected FactoryBean<?> getFactoryBean(String beanName, Object beanInstance) throws BeansException {
		if (!(beanInstance instanceof FactoryBean)) {
			throw new BeanCreationException(beanName,
					"Bean instance of type [" + beanInstance.getClass() + "] is not a FactoryBean");
		}
		return (FactoryBean<?>) beanInstance;
	}

	//移除指定的单例对象
	@Override
	protected void removeSingleton(String beanName) {
		super.removeSingleton(beanName);
		this.factoryBeanObjectCache.remove(beanName);
	}

	//权限管理,系统层面
	protected AccessControlContext getAccessControlContext() {
		return AccessController.getContext();
	}

}

以上就是FactoryBeanRegistrySupport的源代码,大家可以根据源码以及上一篇的例子分析,有什么问题可以给我留言.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring-IOCSpring框架的核心部分之一,它是一种设计模式,全称为Inversion of Control(控制反转)。它通过将对象的创建、依赖关系的管理和对象的生命周期交给Spring容器来实现,从而降低了组件之间的耦合度,提高了代码的可重用性和可维护性。Spring-IOC的实现主要依靠Spring容器,Spring容器是Spring框架的核心,它负责创建、管理和装配Bean对象,其中Bean是Spring框架中最基本的组件。 Spring-IOC的实现主要有两种方式:BeanFactory和ApplicationContext。其中,BeanFactorySpring-IOC的基本实现,而ApplicationContext是BeanFactory的子接口,提供了更多高级特性。ApplicationContext是Spring框架中最常用的IOC容器,它除了提供BeanFactory的所有功能外,还提供了更多的企业级特性,例如AOP、事务管理、国际化、事件传播等。 下面是一个简单的Spring-IOC的例子,假设我们有一个UserService接口和一个UserServiceImpl实现类,我们可以通过Spring-IOC容器来创建和管理UserServiceImpl对象: 1.定义UserService接口和UserServiceImpl实现类 ```java public interface UserService { void addUser(User user); } @Service public class UserServiceImpl implements UserService { @Override public void addUser(User user) { // 添加用户的具体实现 } } ``` 2.在Spring配置文件中配置UserService实例 ```xml <bean id="userService" class="com.example.service.UserServiceImpl"/> ``` 3.在代码中获取UserService实例并使用 ```java ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = context.getBean("userService", UserService.class); User user = new User(); userService.addUser(user); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值