Spring入门(基于Java的容器注解之@Scope和基于泛型的自动装配)

  • Post author:
  • Post category:java


@Scope

在使用@Bean的时候,默认@Bean定义出来的注解是单例的,那么有什么方式可以指定它的范围呢,我们使用@Scope。Bean的作用域包括singleton、prototype、request、session、global session。

@Scope里边的内容和我们之前说到的Bean的范围是一样的,默认value是singleton,可以使用prototype、request、session、global session。

在@Scope里边还有另外一个属性proxyMode,即采用哪一种的代理方式,一种是基于接口的注解,还有一种是TARGET_CLASS,是对于类的代理。

然后看个例子,还是在前一篇的基础上,在StoreConfig中有这样的代码

@Bean(name = "stringStore")
@Scope(value="prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Store stringStore() {
    return new StringStore();
}

设置value为prototype,它的意思是每一次请求都会创建一个新的对象。

写一个单元测试的方法

@Test
public void testScope() {
    Store store = super.getBean("stringStore");
    System.out.println(store.hashCode());

    store = super.getBean("stringStore");
    System.out.println(store.hashCode());
}

这里边取两次对象,输出对象hashCode看是否相同。若两次不同则为正确。

基于泛型的自动装配

@Configuration
public class MyConfiguration{
    @Bean
    public StringStore stringStore(){
        return new StringStore();
    }
    @Bean
    public IntegerStore integerStore(){
        return new IntegerStore();
    }
}

仍然是@Configuration配置两个类StringStore和IntegerStore。

@Autowired
private Store<String> s1;

@Autowired
private Store<Integer> s2;

在进行@Autowired自动装配的时候,两个Store s1和s2,第一个是String第二个是Integer。也就是说通过这种泛型的方式来指定s1和s2分别对应哪一个bean。s1泛型里边指定的是String,那么s1对应的应该是上边的StringStore,s2对应IntegerStore。

还有另一种方法

@Autowired
private List<Store<Integer>> s;

也就是说在一个集合里边的Store对象泛型指定的都是Integer类型的。


例子


将之前的一些类进行修改

接口里指定T泛型:

public interface Store<T> {}

然后在实现类指定它的泛型:

public class StringStore implements Store<String> {

    public void init() {
        System.out.println("This is init.");
    }

    public void destroy() {
        System.out.println("This is destroy.");
    }
}

写一个IntegerStore实现Store接口并指定它的泛型

public class IntegerStore implements Store<Integer> {}

在StoreConfig类中进行声明

@Autowired
private Store<String> s1;

@Autowired
private Store<Integer> s2;

@Bean
public StringStore stringStore() {
    return new StringStore();
}

@Bean
public IntegerStore integerStore() {
    return new IntegerStore();
}

@Bean(name = "stringStoreTest")
// public StringStore stringStoreTest() {
public Store stringStoreTest() {
    System.out.println("s1 : " + s1.getClass().getName());
    System.out.println("s2 : " + s2.getClass().getName());
    return new StringStore();
}

里边有一个方法输出s1和s2的类名。这个方法要注意,由于是借用之前的写过的方法,所以类型是StingStore,但是s1在装配的时候发现有两个StringStore类型。正常情况下会把第一个@Bean注解的StringStore赋值给s1,但是有两个StringStore,会失败。所以把下边的方法类型修改一下。

单元测试类:

@Test
public void testG() {
    StringStore store = super.getBean("stringStoreTest");
}

getBean的时候就会得到StoreConfig中的stringStoreTest方法,还会输出s1和s2两个类的类名。输出s1对应的StringStore,s2对应IntegerStore。

Autowire扩展内容,关于自定义qualifier注解

CustomeAutowireConfigurer是BeanFactoryPostProcessor的子类,通过它可以注册自己的qualifier注解类型(即使没有使用Spring的@Qualifier注解)

<bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
    <property name="customQualifierTypes">
        <set>
            <value>example.CustomQualifier</value>
        </set>
    </property>
</bean>

class指定类,这个类中有个属性customQualifierTypes,具体有哪些类型,我们可以把自己定义的类型放在里边,注意这里是Set,也就是说我们可以放很多个。

该AutowireCandidateResolver决定自动装配的候选者:

-每个bean定义的autowire-candidate值

-任何

<bean/>

中的default-autowire-candidates

-@Qualifier注解及使用CustomAutowireConfigurer的自定义类型。

很少会使用到



版权声明:本文为qq_36206746原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。