9、IoC之依赖注入(2)-bean的代理对象生成

在前面已经封装好BeanDefinition之后,那么接下来就根据指定的BeanDefinition通过反射生成指定的对象。

1、根据目标对象确定实例的产生方式:JDK或者CGLIB。有Override方法目标对象,使用CGLIB方式实例化具体的对象。

	// SimpleInstantiationStrategy
	// 具体的bean实例化
	// JDK或者CGLIB
	
	@Override
	public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
		// 如果没有覆盖,不要用CGLIB覆盖类。 
		if (bd.getMethodOverrides().isEmpty()) {
			Constructor<?> constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				// 获取对象的构造器或许工厂方法
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				// 获取的构造器或许工厂方法失败
				if (constructorToUse == null) {
					// 获取对应类的class对象  采用JDK反射机制
					final Class<?> clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
						// 接口无法实例
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						
						if (System.getSecurityManager() != null) {
							// 匿名内部类 通过反射获取默认构造方法
							constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
								@Override
								public Constructor<?> run() throws Exception {
									return clazz.getDeclaredConstructor((Class[]) null);
								}
							});
						}
						else {
							// 通过待实例化bean的Class对象获取申明的构造器
							constructorToUse =	clazz.getDeclaredConstructor((Class[]) null);
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			// 调用BeanUtils的静态方法instantiateClass
			// 通过constructor.newInstance(args);来实例化对象
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// 使用CGLIB来实例化对象
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

 在上面方法的结尾调用instantiateWithMethodInjection(bd, beanName, owner);方法来通过CGlib方式创建对象,通过代码跟踪,发现该方法的具体实现是在CglibSubclassingInstantiationStrategy中的instantiate(Constructor<?>ctor, Object... args)里面实现的,代码如下:

	// CglibSubclassingInstantiationStrategy
    // 创建一个实现所需查找的动态生成子类的新实例。
	// 参数ctor是构造函数。
	// 如果这是空的,则使用无参数构造函数(无参数化或设置器注入)
	public Object instantiate(Constructor<?> ctor, Object... args) {
		// 使用CGLIB为所提供的bean定义创建一个增强的bean类的子类。
		Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
		Object instance;
		if (ctor == null) {
			// 构造方法为null 使用默认无参构造器
			instance = BeanUtils.instantiateClass(subclass);
		}
		else {
			try {
				// 获取增强的子类构造函数
				Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
				// 获取增强的子类构造器实例化的对象
				instance = enhancedSubclassConstructor.newInstance(args);
			}
			catch (Exception ex) {
				throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
						"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
			}
		}
	
		// 直接在实例上而不是在增强类中(通过增强器)设置回调,
		// 以避免内存泄漏。
		Factory factory = (Factory) instance;
		factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
				new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
				new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
		return instance;
	}

通过JDK和CGlib两种方式,实现了根据BeanDefinition来生成一个指定的类。

至于为什么要用两种不同的方式生成目标实例,原因很简单:JDK是针对接口生成代理对象,而CGlib则是生成目标对象的子类的实例化对象,这个实例化对象的运行时生成的,而且覆盖了父类所有的方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值