Spring提供了三种主要的装配机制:
隐式的 bean 发现机制和自动装配。
在 XML 中进行显式配置。
在 Java 中进行显式配置。
自动化装配 bean
要实现自动化装配的关键之一在于能让Spring知道有哪些组件存在,你需要手动打开Spring的组件扫描。可以在Spring的xml文件中打开,使用
<context:component-scan base-package="com.springbean.*"/>
当然前提是引入了Spring context的命名空间,上面的示例还指定了扫描的包的位置。也可以在java的配置类中启用组件扫描。
package com.springbean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class SpringConfig {
}
注解@ComponentScan指定了spring将扫描这个配置类所在的包及其子包下面的所有类。有了组件扫描后,所有被注解@Component或者@Named注解的类都将被识别为组件类,这两个注解都可以声明组件的名字。
//@Component
@Named("userInterface")
public class UserInterfaceImpl implements UserInterface{
public void userMethod() {
System.out.println("UserInterfaceImpl - userMethod()");
}
}
使用注解@Autowired可以方便的将配置好的bean注入到想要注入的位置。
通过 XML 装配 bean
在spring的xml配置文件中配置装配信息,配置组件bean的话只需要使用<bean>标签即可。
<bean id="userInterface" class="com.springbean.impl.UserInterfaceImpl" />
假如配置的bean下面也有需要注入的参数,比如为userCall注入userInterface的实现类和其他参数那么可以使用两种方式注入参数。
- 使用构造器注入
可以直接使用<constructor-arg>标签。
<util:list id="tagsList">
<value>cool</value>
<value>nice</value>
</util:list>
<bean id="userCall" class="com.springbean.UserCall">
<constructor-arg name="ui" ref="userInterface"/>
<constructor-arg name="username" value="test"/>
<constructor-arg name="tags" ref="tagsList"></constructor-arg>
</bean>
引用另外的bean时使用ref,字符串常量则使用value。
也可以使用c-命名空间,在c-命名空间和模式声明之后
<beans ...... xmlns:c="http://www.springframework.org/schema/c"
...... >
</beans>
<bean id="userCall" class="com.springbean.UserCall" c:ui-ref="userInterface" c:username="test" c:tags="tagsList" />
使用c-命名空间可以明显缩短配置长度。
不过使用构造器注入的时候必须在类中添加对应的构造方法才能有效,因为注入时调用的是类的构造方法,比如userCall类中调用
public UserCall(UserInterface ui, String username, List<String> tags){
this.ui = ui;
this.username = username;
this.tags = tags;
}
- 使用属性注入
直接使用<property>标签
<bean id="userCall" class="com.springbean.UserCall">
<property name="ui" ref="userInterface" />
<property name="username" value="test" />
<property name="tags" value="tagsList" />
</bean>
使用p-命名空间
<bean id="userCall" class="com.springbean.UserCall" p:ui-ref="userInterface" p:username="test" p:tags="tagsList" />
属性注入调用的是setter方法,所以类中要有相应的setter方法。
通过 Java 代码装配 bean
使用@Configuration可以将java的类文件声明成spring的配置类,使用@Bean来声明方法的返回对象要注册为spring的bean对象。而且一般的,方法名即为id名,当然也可以为bean指定名称,通过其@Bean注解的name属性。而当bean中需要注入其他参数或者引用时,将其作为方法的参数即可,Spring会帮你注入这些引用
如下面的userCall方法。
@Configuration
public class SpringConfig {
@Bean
public String username(){
return "test";
}
@Bean
public List<String> tags(){
List<String> tags = new ArrayList<String>();
tags.add("cool");
tags.add("nice");
return tags;
}
@Bean
public UserInterface userInterface(){
return new UserInterfaceImpl();
}
@Bean
public UserCall userCall(UserInterface userInterface, String username, List<String> tags){
UserCall uc = new UserCall();
uc.setUi(userInterface);
uc.setUsername(username);
uc.setTags(tags);
return uc;
}
}
使用java类做配置类使用时同样和xml文件一样需要加载,比如测试时在上下文配置信息@ContextConfiguration上填上配置类。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=com.springbean.SpringConfig.class)
public class MainTest {
@Autowired
private UserCall uc;
@Test
public void test(){
assertNotNull(uc);
}
}
混合使用
无论采用何种方式去声明一个bean,在spring中都可以任意的使用到任何地方去。自动装配与其他两种方式的配合使用最简单,只需要开启组件扫描就行了。
以Java Config为主,在java的配置类中使用xml配置
@Configuration
@ImportResource("classpath:springbean.xml")
public class SpringConfig {
......
}
以xml配置为主,在xml配置中使用java Config,使用<bean>将其导入
<bean class="com.springbean.SpringConfig" />
扩展
@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
Spring帮助我们管理Bean分为两个部分,一个是注册Bean,一个装配Bean。完成这两个动作有三种方式,一种是使用自动配置的方式、一种是使用JavaConfig的方式,一种就是使用XML配置的方式。在自动配置的方式中,使用@Component去告诉Spring,我是一个bean,你要来管理我,然后使用@AutoWired注解去装配Bean(所谓装配,就是管理对象直接的协作关系)。然后在JavaConfig中,@Configuration其实就是告诉spring,spring容器要怎么配置(怎么去注册bean,怎么去处理bean之间的关系(装配))。那么就很好理解了,@Bean的意思就是,我要获取这个bean的时候,你spring要按照这种方式去帮我获取到这个bean。到了使用xml的方式,也是如此。君不见<bean>标签就是告诉spring怎么获取这个bean,各种<ref>就是手动的配置bean之间的关系。
网友评论