09.Spring Framework 之 Lookup

1. Method Injection

详见文档 https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-method-injection

In most application scenarios, most beans in the container are singletons. When a singleton bean needs to collaborate with another singleton bean or a non-singleton bean needs to collaborate with another non-singleton bean, you typically handle the dependency by defining one bean as a property of the other. A problem arises when the bean lifecycles are different. Suppose singleton bean A needs to use non-singleton (prototype) bean B, perhaps on each method invocation on A. The container creates the singleton bean A only once, and thus only gets one opportunity to set the properties. The container cannot provide bean A with a new instance of bean B every time one is needed.

在大多数应用场景中,容器中的大多数 bean 是单例的。 当单例 Bean 需要与另一个单例 Bean 协作或非单例 Bean 需要与另一个非单例 Bean 协作时,通常可以通过将一个 Bean 定义为另一个 Bean 的属性来处理依赖性。 当 bean 的生命周期不同时会出现问题。 假设单例 bean A 可能需要使用非单例(原型)bean B,也许是在 A 的每个方法调用上使用。容器仅创建一次单例 bean A,因此只有一次机会来设置属性。 每次需要一个容器时,容器都无法为 bean A 提供一个新的 bean B 实例。

A solution is to forego some inversion of control. You can make bean A aware of the container by implementing the ApplicationContextAware interface, and by making a getBean(“B”) call to the container ask for (a typically new) bean B instance every time bean A needs it.

一个解决方案是放弃某些控制反转。 您可以通过实现 ApplicationContextAware 接口,并通过对容器进行 getBean("B") 调用来使 bean A 知道该容器,以便每次 bean A 需要它时都请求一个(通常是新的)bean B 实例。

Lookup method injection is the ability of the container to override methods on container-managed beans and return the lookup result for another named bean in the container. The lookup typically involves a prototype bean, as in the scenario described in the preceding section. The Spring Framework implements this method injection by using bytecode generation from the CGLIB library to dynamically generate a subclass that overrides the method.

查找方法注入是容器覆盖容器管理的 Bean 上的方法并返回容器中另一个命名 Bean 的查找结果的能力。 查找通常涉及原型 bean,如上一节中所述。Spring 框架通过使用从 CGLIB 库生成字节码来动态生成覆盖该方法的子类来实现此方法注入。

2. 核心代码

代码已经上传至 https://github.com/masteryourself-tutorial/tutorial-spring ,详见 tutorial-spring-framework/tutorial-spring-framework-injection-lookup 工程

1. Dog
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Dog {
}
2. Person
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
@ToString
public class Person {

    /**
     * 会带来因为作用域范围引出的问题
     */
    @Autowired
    private Dog dog;

    /**
     * 使用 {@link Lookup} 避免原型问题
     *
     * @return
     */
    @Lookup
    public Dog dog() {
        return null;
    }

    public void doSomething() {
        System.out.println("使用 @Autowired:" + dog.hashCode());
        System.out.println("使用 @Lookup:" + dog().hashCode());
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
[main] ERROR org.springframework.boot.SpringApplication - Application run failed org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bizFactory': Unsatisfied dependency expressed through field 'context'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'brand': Lookup method resolution failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [com.fmall58.wechatsub.business.bizs.BrandHelper] from ClassLoader [sun.misc.Launcher$AppClassLoader@5c647e05] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1395) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:849) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) at com.fmall58.wechatsub.NServerApplication.main(NServerApplication.java:16) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'brand': Lookup method resolution failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class
07-20

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值