`

lookup-method (2)

阅读更多

转自: http://tjc.iteye.com/blog/339354


情景设定:
    首先简单介绍一下Spring的Bean作用域
   

Spring reference 写道
作用域                 描述
singleton      在每个Spring IoC容器中一个bean定义对应一个对象实例。

prototype      一个bean定义对应多个对象实例。


request        在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各 自的bean实例, 它们

                      依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。

session        在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web

                      的Spring ApplicationContext情 形下有效。

global session         在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet

                          context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。


以上就是Spring对于容器中bean的几种作用域含义的简单描述。我们重点关注一下singleton,prototype这两种作用域。
    ★★关于singleton:

Spring reference 写道
The scope of the Spring singleton is best described as per container and per bean. This means that if you define one bean for a particular class in a single Spring container, then the Spring container will create one and only one instance of the class defined by that bean definition. The singleton scope is the default scope in Spring.


引用
把Spring的 singleton作用域描述成一个container对应一个bean实例最为贴切。亦即,假如在单个Spring容器内定义了某个指定class的 bean,那么Spring容器将会创建一个且仅有一个 由该bean定义指定的类实 例。Singleton作用域是Spring中的缺省作用域。


use it like this

引用
<bean id="beanId" class="com.yourcompany.project.Bean" scope="singleton" />


or

引用
<bean id="beanId" class="com.yourcompany.project.Bean" singleton="true" />



    ★★关于prototype:

Spring reference 写道

The non-singleton, prototype scope of bean deployment results in the creation of a new bean instance every
time a request for that specific bean is made (that is, it is injected into another bean or it is requested via a programmatic getBean() method call on the container). As a rule of thumb, you should use the prototype scope for all beans that are stateful, while the singleton scope should be used for stateless beans.


引用
Prototype作用域 的bean会导致在每次 对该bean请求(将其注入到另一个bean中,或者以程序 的方式调用容器的getBean()方法)时都会创建一个新的 bean实例。根据经 验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。


use it like this

引用
<bean id="beanId" class="com.yourcompany.project.Bean" scope="prototype" />


or

引用
<bean id="beanId" class="com.yourcompany.project.Bean" singleton="false" />


顺便注意一下:

引用
对 prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。

更多请参考Spring reference 3.4.2. The prototype scope

OK,问题出来了

引用
当使用依 赖于prototype bean的singleton-scoped bean时,请注意依赖是在实例化时处理的。这也就是说,如果要把一个prototype-scoped bean注入到singleton-scoped bean,实际上只是实例化一个新的prototype bean注入到 singleton bean...但这是全部。这种情况下,singleton-scoped bean获得的prototype实例是唯一的。

然而,你可能需要在运行期让singleton-scoped bean每次都获得prototype-scoped bean的新实例。在这种情况下,只将prototype-scoped bean注入到你的singleton bean中是没有用的,因为正如上文所说的,仅仅在当Spring容器实例化singleton bean并且处理注入的依赖时,生成唯一实例。


这种情况改怎么解决呢?
oh,我不用Spring 行吗? 行,你又回到起点了....

Spring 为我们提供了方法注入lookup-method 来解决这个问题。我们来体验一下。
一下code参考http://java.ccidnet.com/art/3739/20060317/481857_1.html

在之前搭建的环境的基础上添加cglib库,copy SPRING_HOME/lib/cglib-2.1_x.jar to classpath.
新建com.ufinity.spring.lookupmethod package;
编写如下文件
Hello.java

public interface Hello {
    public Random getRandom();
    public abstract Random createRandom();
}

HelloAbstract.java

public abstract class HelloAbstract implements Hello {
    private Random random;

    public Random getRandom() {
        return random;
    }

    public void setRandom(Random random) {
        this.random = random;
    }

    public abstract Random createRandom();
}

 Random.java

public class Random {
    private int i = (int) (100 * Math.random());

    public void printRandom() {
        System.out.println("输出随机整数:  " + i);
    }
}

配置你的bean 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    <bean id="ran" class="com.ufinity.spring.lookupmethod.Random" scope="prototype"/>
    
    <bean id="hello" class="com.ufinity.spring.lookupmethod.HelloAbstract">
        <lookup-method name="createRandom" bean="ran"/>
        <property name="random">
            <ref local="ran"/>
        </property>
    </bean>
    
</beans>

OK,just test
LookUpMethodTest.java

public class LookUpMethodTest {
	@Test
	public  void testLookupMethod() {

        Resource res = new ClassPathResource("applicationContext-lookupmethod.xml");
        BeanFactory ft = new XmlBeanFactory(res);

        Hello h = (Hello) ft.getBean("hello");

        Random r1 = h.getRandom();
        Random r2 = h.getRandom();
        System.out.println("没有采用Lookup方法注入:");
        System.out.println("Random 的两个实例指向同一个引用:" + (r1 == r2));
        r1.printRandom();
        r2.printRandom();

        Random r3 = h.createRandom();
        Random r4 = h.createRandom();
        System.out.println("\n采用Lookup方法注入:");
        System.out.println("Random 的两个实例指向同一个引用:" + (r3 == r4));
        r3.printRandom();
        r4.printRandom();

    }

}

output:

引用
没有采用Lookup方法 注入:
Random 的两个实例指向同一个引用:true
输出随机整数:  65
输出随机整数:  65

采用Lookup方法注入:

Random 的两个实例指向同一个引用:false
输出随机整数:  97
输出随机整数:  69

 



 

 

 

 

 

 

 

 

 

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    深入理解Spring中的Lookup(方法注入)

    &lt;lookup-method name="getClassB" bean="classB"/&gt; ``` Java配置: ```java @Configuration public class AppConfig { @Bean @Scope("prototype") public ClassB classB() { return new ClassB(); } @...

    lookup-dns-cache:通过避免线程池并为特定主机名使用DNS TTL缓存来加速nodejs`dns.lookup`方法的实现

    // With "request" modulerequest ( { url : 'http://google.com' , method : 'GET' , lookup : lookup} , ( error , response , body ) =&gt; { // ...} ) ;// Direct usagelookup ( 'google.com' , { } , ( error , ...

    dns-lookup-cache:通过避免线程池并为特定主机名使用DNS TTL缓存来加速nodejs“ dns.lookup”方法的实现

    dns-lookup- dns.lookup... method : 'GET' , lookup : lookup } , ( error , response , body ) =&gt; { // ... } ) ; // Direct usage lookup ( 'google.com' , { } , ( error , address , family ) =&gt; { // ... }

    Spring ApplicationContext.xml配置的12个技巧演示教学.pdf

    lookup-method 可以用来注入 Bean,避免了硬编码的依赖关系。 7. 使用 factory-method 来实例化 Bean factory-method 可以用来实例化 Bean,提供了更多的灵活性。 8. 使用 depends-on 来指定 Bean 的依赖关系 ...

    Spring实战之协调作用域不同步的Bean操作示例

    `&lt;lookup-method&gt;`元素用于定义一个lookup-method,`&lt;property&gt;`元素用于设置Bean的属性值。 接口和实现类 在本文示例中,我们定义了两个接口:Dog和Person。Dog接口定义了一个run方法,Person接口定义了一个hunt...

    JAVA spring 系列案例50个和学习资料

    Spring系列第12篇:lazy-init:bean延迟初始化Spring系列第13篇:使用继承简化bean配置(abstract & parent)Spring系列第14篇:lookup-method和replaced-method比较陌生,怎么玩的?Spring系列第15篇:代理详解(Java...

    Remote-method-invocation

    远程方法调用(Remote Method Invocation,RMI)是Java编程语言中的一种机制,它允许一个对象在某个Java虚拟机(JVM)上执行方法,而该对象实际位于另一个JVM中。这种技术使得分布式计算成为可能,使得Java应用程序...

    spring学习笔记

    2. 使用方法注入(lookup-method),让容器在运行时重写bean的方法,返回其他bean的新实例。 Spring还提供了定制bean生命周期行为的机制。例如,可以在bean初始化完成后执行特定操作: 1. 使用`init-method`属性,...

    RESTLET开发(三)

    &lt;lookup-method name="create" bean="StudentResource"/&gt; &lt;lookup-method name="create" bean="StudentsResource"/&gt; ``` 这段配置指定了两个URL路径:`/student/{studentId}` 和 `/student`,...

    RMI客户端调用远程服务器方法-远程方法调用

    在Java编程领域,远程方法调用(Remote Method Invocation,RMI)是一种强大的技术,它允许一个Java对象在某个JVM(Java虚拟机)上执行另一个JVM中的对象的方法。RMI是分布式计算的基础,尤其在构建分布式应用程序时...

    spring 静态实例化

    例如,在提供的代码示例中,我们看到了一个名为`useType`的Bean实例被定义,并且通过`&lt;lookup-method&gt;`指定了一个名为`getMyType`的方法,该方法返回另一个名为`test.sat.type.MyType.TypeOne`的Bean实例。...

    spring-beans-3.0.xsd

    在`&lt;bean&gt;`元素中,`lookup-method`和`replaced-method`属性的引入,使得在运行时动态查找或替换bean的方法成为可能,这是对AOP(面向切面编程)的一种补充,提供了更细粒度的控制。 除此之外,`&lt;util&gt;`命名空间在...

    Spring源码总结.pdf

    在解析`bean`时,会创建`GenericBeanDefinition`对象,设置属性,处理元数据、lookup-method、replaced-method、构造参数、属性、qualifier等。 4. **自定义标签解析**: - 自定义标签解析涉及到Spring的命名空间...

    Spring 框架中注入或替换方法实现

    在上面的示例中,我们使用 lookup-method 标签来注入 getAuthor() 方法,该方法将返回一个新的 Author Bean 的实例。 四、单元测试 为了验证上述实现,我们可以编写单元测试来测试该实现。例如,我们可以编写以下...

    Spring2.0的配置2

    10. **使用`&lt;lookup-method&gt;`和`&lt;factory-method&gt;`**: 这两个元素允许在运行时动态创建bean,而不是在配置时静态定义。这对于实现策略模式或动态代理等场景很有帮助。 11. **使用`&lt;bean&gt;`的`lazy-init`属性**: ...

    Spring中xml的配置[定义].pdf

    除了这些核心概念,Spring的XML配置还包括其他元素,如`&lt;import&gt;`引入其他配置文件,`&lt;alias&gt;`为bean定义别名,以及`&lt;lookup-method&gt;`和`&lt;replaced-method&gt;`来处理方法的动态代理等。XML配置提供了一种声明式的方式...

    unigui0.83.5.820

    - 0000776: UniDBLookUpXXX: ListSource cursor position does not follow Lookup value - 0000773: UniDBGrid: Column.Title.Font/Color - 0000771: UniDBGrid: Column.Font property - 0000772: UniDBGrid: ...

    wget-1.11.4-1

    --dns-timeout=SECS set the DNS lookup timeout to SECS. --connect-timeout=SECS set the connect timeout to SECS. --read-timeout=SECS set the read timeout to SECS. -w, --wait=SECONDS wait SECONDS ...

Global site tag (gtag.js) - Google Analytics