Spring管理Bean-IOC-05
3.基于注解配置bean
3.3自动装配
基本说明:
-
基于注解配置bean,也可以实现自动装配,使用的注解是:@AutoWired或者@Resource
-
@AutoWired 的规则说明
(1)在IOC容器中查找待装配的组件的类型,如果有唯一的bean装配(按类型),则使用该bean装配
(2)如果待装配的类型对应的bean在IOC容器中有多个,则使用待装配的属性的属性名作为id值进行查找,找到就装配,找不到就抛异常
-
@Resource 的规则说明
(1)@Resource 有两个属性比较重要,分别是name和type
Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType的自动注入策略
(2)如果@Resource没有指定name或者type,则先使用ByName注入策略,如果匹配不上,再使用byType策略,如果都不成功就会报错
-
不管是@AutoWired 还是 @Resource,都保证属性名是规范的写法就可以注入。
-
除了有特殊要求,一般推荐使用@Resource
3.3.1应用实例1-@AutoWired
应用实例需求:
- 以Action、Service、Dao几个组件来进行演示
- 这里演示UserAction和UserService的两级自动组装
UserService:
package com.li.component;
import org.springframework.stereotype.Service;
/**
* @author 李
* @version 1.0
* @Service 标识该类是一个Service类/对象
*/
@Service
public class UserService {
public void hi(){
System.out.println("UserService hi()...");
}
}
UserAction:
package com.li.component;
import org.springframework.stereotype.Controller;
/**
* @author 李
* @version 1.0
* @Controller 标识该类是一个控制器Controller,通常该类是一个Servlet
*/
@Controller
public class UserAction {
private UserService userService;
public void sayOk() {
System.out.println("UserAction 的 sayOk()");
userService.hi();
}
}
beans05.xml指定要扫描的包:
<context:component-scan base-package="com.li.component"/>
测试类:
//通过注解来配置Bean
@Test
public void setProByAutowired() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans05.xml");
UserAction userAction = ioc.getBean("userAction", UserAction.class);
System.out.println("userAction=" + userAction);
userAction.sayOk();
}
如下,当运行到userAction.sayOk();
时抛出空指针异常:
这是因为userAction中的属性userService指向null,即没有正确的装配UserService对象。
添加@Autowired注解:
在IOC容器中查找待装配的组件的类型,如果有唯一的bean装配(按照类型组装),则使用该bean装配
@Controller
public class UserAction {
//在IOC容器中查找待装配的组件的类型,如果有唯一的bean装配(按类型),则使用该bean装配
@Autowired
private UserService userService;
public void sayOk() {
System.out.println("UserAction 的 sayOk()");
userService.hi();
}
}
运行结果如下,成功调用了userService.hi()方法,说明userService对象已经成功装配:
现在我们在beans05.xml容器中再配置两个UserService对象
spring允许同时使用xml配置文件和注解的方式配置bean
<context:component-scan base-package="com.li.component"/>
<!--配置两个UserService对象-->
<bean class="com.li.component.UserService" id="userService200"/>
<bean class="com.li.component.UserService" id="userService300"/>
此时在ioc容器中就有三个UserService对象:
(1)对于自动扫描进去的UserService对象,它的id为它的类名(首字母小写)。
(2)在xml文件中配置的两个UserService对象,它们的id为上面设置的id(userService200、userService300)
现在我们重新运行测试方法:
//通过注解来配置Bean
@Test
public void setProByAutowired() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans05.xml");
UserAction userAction = ioc.getBean("userAction", UserAction.class);
System.out.println("userAction=" + userAction);
userAction.sayOk();
}
问题一:运行会不会报错?
问题二:@AutoWired注解的属性进行自动装配的时候,装配的是哪一个UserService对象?
@Autowired
private UserService userService;
答案一:没有报错
答案二: 在@AutoWired注解中,如果待装配的类型对应的bean在IOC容器中有多个,则使