11-bean创建流程2

1.dependsOn

某些bean依赖一些bean,可以将依赖的ban先实例化和初始化。

2. lookup-method标签或@LookUp

单例模式的bean只会被创建一次,IoC容器会缓存该bean实例以供下次使用;原型模式的bean每次都会创建一个全新的bean,IoC容器不会缓存该bean的实例。那么如果现在有一个单例模式的bean引用了一个原型模式的bean呢?如果无特殊处理,则被引用的原型模式的bean也会被缓存,这就违背了原型模式的初衷,这时使用lookup-method注入可以解决该问题。

package com.mashibing.methodOverrides.lookup;

public class Fruit {
    public Fruit() {
        System.out.println("I got Fruit");
    }
}
package com.mashibing.methodOverrides.lookup;

public class Apple extends Fruit {
    public Apple() {
        System.out.println("I got a fresh apple");
    }
}
package com.mashibing.methodOverrides.lookup;

public class Banana extends Fruit {
    public Banana() {
        System.out.println("I got a  fresh bananer");
    }
}
package com.mashibing.methodOverrides.lookup;

public abstract class FruitPlate{
    // 抽象方法获取新鲜水果
    public abstract Fruit getFruit();
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="apple" class="com.mashibing.methodOverrides.lookup.Apple" scope="prototype"/>
    <bean id="banana" class="com.mashibing.methodOverrides.lookup.Banana" scope="prototype" />

    <bean id="fruitPlate1" class="com.mashibing.methodOverrides.lookup.FruitPlate">
        <lookup-method name="getFruit" bean="apple"/>
    </bean>
    <bean id="fruitPlate2" class="com.mashibing.methodOverrides.lookup.FruitPlate">
        <lookup-method name="getFruit" bean="banana"/>
    </bean>
</beans>

关键点:

	// Prepare method overrides.
	try {
		mbdToUse.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	}

原理是:使用cglib生产代理类,复写方法。CglibSubclassingInstantiationStrategy#intercept

	@Override
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {
		// Cast is safe, as CallbackFilter filters are used selectively.
		LookupOverride lo = (LookupOverride) getBeanDefinition().getMethodOverrides().getOverride(method);
		Assert.state(lo != null, "LookupOverride not found");
		Object[] argsToUse = (args.length > 0 ? args : null);  // if no-arg, don't insist on args at all
		if (StringUtils.hasText(lo.getBeanName())) {
		    // 代理之后,原型bean每次都新建
			return (argsToUse != null ? this.owner.getBean(lo.getBeanName(), argsToUse) :
					this.owner.getBean(lo.getBeanName()));
		}
		else {
			return (argsToUse != null ? this.owner.getBean(method.getReturnType(), argsToUse) :
					this.owner.getBean(method.getReturnType()));
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值