Spring装配Bean的3种方式解析

来源:互联网 发布:为什么蔬菜不好吃知乎 编辑:程序博客网 时间:2024/06/01 22:19

在Spring中,依赖注入是Spring最重要的特性之一。我们所使用的Bean都是通过依赖注入完成的。在如今的Spring中,提供了3中装配Bean的方式:
1.在XML中显式配置;
2.在Java中显式配置;
3.隐式的bean发现机制和自动装配。
接下来通过一个例子一一的实现这3种配置方式。

public interface Login {    void login();}@Componentpublic class UserLogin implements Login {    public void login() {        System.out.println("login success!");    }}@Componentpublic class LoginController {    private Login login;    public Login getLogin() {        return login;    }    @Autowired\\自动注解的构造注解方式    public LoginController(Login login) {        this.login = login;    }    @Autowired \\1.通过Java方式配置Bean时不需要此注解    \\自动注解的属性注解方式    public void setLogin(Login login) {        this.login = login;    }    public void login() {        login.login();    }}@Configuration@ComponentScan(basePackages{"com.ls.loginModel"})\\扫描bean所在的包,可以配置多个包参数public class LoginConfig {} \\自动化配置类@Configuration@ComponentScan(basePackages{"com.ls.loginModel"})\\扫描bean所在的包,可以配置多个包参数public class LoginConfig {\\Java方式配置类    @Bean    public Login userLogin() {        return new UserLogin();    }    @Bean    public LoginController loginController(Login login) {        LoginController controller = new LoginController();        controller.setLogin(login);        return controller;    }}\\XML方式配置自动扫描包<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">    <!-- 自动扫描包(自动注入) -->    <context:component-scan base-package="com.ls.springModel" /></beans>\\XML方式装配bean<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">class="com.ls.springModel.UserLogin"/>    <bean id="loginController" class="com.ls.springModel.Logintroller">        <constructor-arg ref="login"></constructor-arg> <!--构造注入 对应构造函数 -->        <property name="login" ref="login"></property><!--属性注入 对应setter方法  -->    </bean></beans>public class LoginWindow {    \\测试代码    @SuppressWarnings("resource")    public static void main(String[] args) {        ApplicationContext javaContext = new AnnotationConfigApplicationContext(LoginConfig.class);        LoginController login = javaContext.getBean(LoginController.class);        login.login();        ApplicationContext xmlContext = new ClassPathXmlApplicationContext("spring.xml");        LoginController login1 = xmlContext.getBean(LoginController.class);        login1.login();    }}

一、隐式的bean发现机制和自动装配:
隐式的配置bean的有两个关键点:就是组件的扫描(与@Component注解有关)以及自动装配(与@Autowired注解有关)。通过上面的代码可以看到,在每个bean的类中都有一个@Component注解,这个注解的作用就是声明这是一个bean组件,在Spring启动时就可以将这个类作为一个bean加入上下文中。当然我们同样可以通过XML配置扫描包。当通过XML方式扫描包后,也就不需要LoginConfig这个配置类了。同时,如果两个类之间存在依赖时,就需要用到@Autowired注解,这个注解的作用就是将类自动注入到所用到的参数中。
总的来说自动装配是一种十分简洁的配置方式,我们不需要编写XML文件来装配bean,这样也就省下了维护XML文件的麻烦。
二、通过Java方式装配Bean
以Java方式来装配Bean就是在Java代码中对bean进行声明。通过上面的代码我们可以看出,Java方式配置与自动装配有两个区别,那就是在Java方式配置中需要再配置类里对要装配的bean进行声明,以@Bean注解为标志,代表着这是将要注入的bean。同时,我们看到具有依赖的两个类也在对bean的声明中解决了。
三、通过XML方式装配Bean
XML装配方式是Spring刚刚出现的时候最主要的装配方式。通过XML装配方式,我们就不需要在代码中进行注解了。但是需要将用到的所有bean都写入到XML文件中,在上述代码中我们也可以看到相应的配置。
至此,三种配置方式都已经实现了。

现在我们来讲一下在自动装配时有多个类继承同一个接口时如何解决bean之间的冲突。
解决方案:采用限定符注解。
在这个例子中有UserLogin和ManagerLogin继承了Login接口,当使用自动化装配时,就可以采用限定符来区分这两个bean。在下面的代码中有@Qualifier这个注解来定义bean的限定符。其中UserLogin的限定符是userLogin(这是默认的bean,同样的也可以自定义一个限定符),ManagerLogin的限定符是managerLogin。在注入的时候只要加上相应的限定符就可以区分实现同一个接口的不同bean了。另外,一个bean的限定符也可以有多个(比如在UserLogin上再加入一个@Qualifier(”user”),那么UserLogin的限定符就是user和userLogin了)。

@Component@Qualifier("userLogin")public class UserLogin implements Login {    public void login() {        System.out.println("login success!");    }}@Component@Qualifier("managerLogin")public class ManagerLogin implements Login {    public void login() {        System.out.println("login success!");    }}

总结:对比上述三种Bean的装配方式,我们可以明显的看出使用自动化隐式装配是最好的方式,相较于另外两种,这种方式不需要维护一些bean的配置代码,省去了不少麻烦。当然对于一些jar包中的类,由于无法加入注解我们还是要使用显示装配的。另外,Java装配方式又优于XML装配方式,因为在Java装配方式中,我们可以定制化bean的实例化,可以在声明的时候加入我们定制的代码。总之在使用中灵活运用是最好的,同时也推荐混合使用。

0 0
原创粉丝点击