Spring基于注解方式装配Bean

开启使用注解代理配置文件

Spring提供了组件扫描,来进行对指定包进行扫描,对拥有注解的类进行实例化等操作。

<!--
    使用注解之前,我们要先导入4+2+aop的jar包
    同时引入约束 beans+context 
-->
<!--组件扫描:Spring容器会扫描这个包里所有类,从类的注解信息中获取Bean的信息-->
    <context:component-scan base-package="com.pngyul.domain"></context:component-scan>  
    </beans>  

基于注解方式装配Bean

Spring从2.0开始引入基于注解的配置方式,并且不断的进行完善。通过注解的方式可以直接在类上定义Bean的信息,非常方便。

@Component注解来对类进行标注,它可以被Spring容器识别,Spring容器将自动将类转换为容器管理的Bean。

//使用@Component注解定义Bean ,和<bean id="user" class="com.cad.domain.User">是等效的。
@Component("account")
public class Account {
    private int id;
    private String name;
    private String money;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getMoney() {
        return money;
    }
    public void setMoney(String money) {
        this.money = money;
    }
    @Override
    public String toString() {
        return "Account [id=" + id + ", name=" + name + ", money=" + money + "]";
    }
}

除了@Component外,Spring提供了三个功能和@Component等效的注解。
它们一般用于web项目,对DAO,service,web层进行注解,所以也称为Bean的衍生注解。

  • @Repository:对DAO实现类进行注解

  • @Service:对service实现类进行注解

  • @Controller:对web层Controller实现类进行注解

之所以提供这三个特殊的注解,是为了让注解类本身的用途清晰化,此外,Spring还赋予了一些特殊的功能。我们在项目开发中应该尽量使用这种形式

注解方式配置Bean的作用范围和生命过程方法

通过注解配置的Bean和通过< bean >配置的Bean一样,默认的作用范围都是singleton,Spring为注解配置提供了一个@Scope的注解,显式指定Bean的作用范围。

@Controller("user") 
//指定作用范围为多例prototype
@Scope("prototype")
public class User {
    public void say(){
        System.out.println("hello.word");
    }
}

Spring定义的@PostConstruct和@PreDestroy两个注解相当于bean的init-method和destory-method属性的功能

@Controller("account")
@Scope("prototype")
public class Account {
    public void save() {
        System.out.println("hello.word");
    }

    @PostConstruct
    public void myinit() {
        System.out.println("初始化....");
    }

    @PreDestroy
    public void mydestory() {
        System.out.println("销毁中....");
    }

}

注解方式注入一般类型属性

Spring为我们提供了注解 @value,用于对一般属性注入,可以不用提供set方法

@Value("Tom")
private String nmae;
@Value("22")
private int age;

//它是通过反射的Field赋值,破坏了封装性

提供set方法的也可以这样注入

@Value("Tom")
Public void setName(String name){
    this.name = name;
}

//通过set方法赋值,推荐使用.

然而在实际开发者中,尽管实际是破坏了对象的封装性,但开发者还是喜欢用第一种方式注入属性

注解方式注入引用类型属性

//会根据类型自动注入
@Autowired  
private UserService userservice;
//@Autowired可以对类成员变量的set方进行注解。
//对set方法使用注解,UserDao的实例就会被注入进来
@Autowired
public void  setUserdao(UserDao userdao){
     this.userdao=userdao;
}

问题:@Autowired默认按类型匹配的方式,在容器中查找匹配的Bean,当有且只有一个匹配的Bean时,Spring将其注入到@Autowired注解的变量中。但是如果容器中有超过一个以上的匹配Bean时,例如有两个UserService类型的Bean,这时就不知道将哪个Bean注入到变量中,就会出现异常

为了解决这个问题,Spring可以通过@Qualifier注解来注入指定Bean的名称。

public class UserAction {
     @Autowired 
     //指定指定Bean的名称
     @Qualifier("userservice")
     private UserService userservice;
 }

还有一种更为便捷的注解方式注入属性@Resource,相当于@Autowired 和@Qualifier一起使用

@Resource(name="userservice")
private UserService userservice;

整合多个Spring配置文件

对于一个大型项目而言,可能有多个XML配置文件,在启动Spring容器时,可以通过一个String数组指定这些配置文件。Spring还允许我们通过< import >标签将多个配置文件引入到一个文件中,进行配置文件的集成,这样启动Spring容器时,就仅需指定这个合并好的配置文件即可。

  • 第一种方式,使用String数组指定所有配置文件
ApplicationContext ac=new ClassPathXmlApplicationContext(new String[]{"bean1.xml","bean2.xml"});
  • 第二种方式,使用import标签
 //resource属性指定配置文件位置,支持Spring标准的资源路径
 <import resource="classthpath:com/cad/domain/bean1.xml"/>
 <import resource="classthpath:com/cad/domain/bean2.xml"/>

第一种方式并不容易维护,我们在开发中推荐使用第二种方式。

spring与JUnit整合测试

以前,我们在测试的时候,都要写 ApplicationContext ac=new ClassPathXmlApplicationContext(“applicationContext.xml”),然后再获取bean对象。

现在使用JUnit,可以直接使用注解来配置,不再需要手写代码

例如下面这个例子:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {
    @Resource(name="accountService")
    private AccountService as;

    @Test
    public void fun1(){

        as.transfer(1, 2, 100d);
    }

猜你喜欢

转载自blog.csdn.net/PNGYUL/article/details/81637536