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) {
< = money;
}
@Override
public String toString() {
return"Account [id=" + id + ", name=" + name + ", money=" + money + "]";
}
}
除了@Component外,Spring提供了三个功能和@Component等效的注解。
它们⼀般⽤于web项⽬,对DAO,service,web层进⾏注解,所以也称为Bean的衍⽣注解。
@Repository:对DAO实现类进⾏注解resource和autowired注解的区别
@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[]{"l","l"});
第⼆种⽅式,使⽤import标签
//resource属性指定配置⽂件位置,⽀持Spring标准的资源路径
<import resource="classthpath:com/cad/l"/>
<import resource="classthpath:com/cad/l"/>
第⼀种⽅式并不容易维护,我们在开发中推荐使⽤第⼆种⽅式。
spring与JUnit整合测试
以前,我们在测试的时候,都要写 ApplicationContext ac=new ClassPathXmlApplicationContext(“l”),然后再获取bean对象。
现在使⽤JUnit,可以直接使⽤注解来配置,不再需要⼿写代码
例如下⾯这个例⼦:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("l") public class Demo {
@Resource(name="accountService")
private AccountService as;
@Test
public void fun1(){
}