Spring学习(一)-装配Bean的3种方式

简介

在Spring中,依赖注入是Spring最重要的特性之一。我们所使用的Bean都是通过依赖注入完成的。在如今的Spring中,提供了3中装配Bean的方式:

  1. 在XML中显式配置;
  2. 在Java中显式配置;
  3. 隐式的bean发现机制和自动装配。
Bean的装配

接下来通过一个例子一一的实现这3种配置方式。

public interface Login {
    void login();
}
@Component
public class UserLogin implements Login {
    public void login() {
        System.out.println("login success!");
    }
}
//隐式的Bean发现机制和自动注解
@Component
public class LoginController {
    @Autowired //在属性上添加注解
    @Resource //在属性上添加注解
    private Login login;
    public Login getLogin() {
        return login;
    }
    /**
     * 常用的注解有两种:@Autowired,@Resource
     * @autowired 是通过类的类型装配Bean
     * @Resource 是通过类的名称装配bean,名称默认为字段名称或setter方法
     */
    @Autowired  //按照类型装配,可以在构造方法中添加改注解
    @Resource("userLogin") //注入名称为"userLogin"的Bean
    public LoginController(Login login) {
        this.login = login;
    }
    @Autowired  //在setter方法上添加改注解
    @Resource("userLogin") //注入名称为"userLogin"的Bean
    public void setLogin(Login login) {
        this.login = login;
    }
    public void login() {
        login.login();
    }
}
@Configuration
@ComponentScan
(basePackages{"com.ls.loginModel"})
//扫描bean所在的包,可以配置多个包参数
public class LoginConfig {} //自动化配置类

//Java显示配置
@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();
    }
}
3种装配方式说明

1.隐式的bean发现机制和自动装配

隐式的配置bean的有两个关键点:就是组件的扫描(与@Component注解有关)以及自动装配(与@Autowired注解有关)。通过上面的代码可以看到,在每个bean的类中都有一个@Component注解,这个注解的作用就是声明这是一个bean组件,在Spring启动时就可以将这个类作为一个bean加入上下文中。当然我们同样可以通过XML配置扫描包。当通过XML方式扫描包后,也就不需要LoginConfig这个配置类了。同时,如果两个类之间存在依赖时,就需要用到@Autowired注解,这个注解的作用就是将类自动注入到所用到的参数中。
总的来说自动装配是一种十分简洁的配置方式,我们不需要编写XML文件来装配bean,这样也就省下了维护XML文件的麻烦。

2.通过Java方式装配Bean

以Java方式来装配Bean就是在Java代码中对bean进行声明。通过上面的代码我们可以看出,Java方式配置与自动装配有两个区别,那就是在Java方式配置中需要再配置类里对要装配的bean进行声明,以@Bean注解为标志,代表着这是将要注入的bean。同时,我们看到具有依赖的两个类也在对bean的声明中解决了。

3.通过XML方式装配Bean

XML装配方式是Spring刚刚出现的时候最主要的装配方式。通过XML装配方式,我们就不需要在代码中进行注解了。但是需要将用到的所有bean都写入到XML文件中,在上述代码中我们也可以看到相应的配置。
至此,三种配置方式都已经实现了。

解决@Autowried的一些冲突情况

在这个例子中有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的实例化,可以在声明的时候加入我们定制的代码。总之在使用中灵活运用是最好的,同时也推荐混合使用。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值