Spring管理Bean(注解)-IOC
Spring管理Bean(注解)-IOC
注解方式配置bean
基本介绍
基于注解配置bean,主要是项目中开发的组件,比如 Controller、Service、DAO
组件注解的形式
- @Component 表示当前注解标识的是一个组件(不确定是哪一层时用Component)
- @Controller 表示当前注解标识的是一个控制器, 通常用于 Servlet
- @Service 表示当前注解标识的是一个处理业务逻辑的类, 通常用于 Service 类
- @Repository 表示当前注解标识的是一个持久化层的类, 通常用于 Dao 类
配置bean.xml文件
常规配置被扫描包路径
1
<context:component-scan base-package="fullPath" />
【注意】
- 使用注解配置bean时,需要引入aop的jar
- 需要导入context名称空间
- base-package=”fullPath” 是指定需要扫描的包,ioc容器将检测该包及其子包中被注解标识了的类
- 路径也可以用通配符来表述,com.mhl.spring.* ,即spring下面的所有包及其子包
指定需要扫描的资源模式
1
2<!--->将会扫描dao包下,由User开头的类<--->
<context:component-scan base-package="com.mhl.spring.dao" resource-pattern="User*.class"/>排除指定的注解类
1
2
3
4<!--->排除由Repository注解标识的类<--->
<context:component-scan base-package="com.example">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context>扫描指定的注解类
1
2
3
4<!--->扫描由Repository注解标识的类<--->
<context:component-scan base-package="com.example" use-default-filters="false">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context>【注意】和排除不同的是,需要将默认的过滤机制设为false。
id
默认情况下,标记注解后,类名首字母小写作为id的值,也可以使用注解的value属性指定id值,并且value可以省略。
1
2
自动装配
@AutoWired 和 @Resource
@AutoWired
规则说明:
- 在 IOC 容器中查找待装配的组件的类型,如果有唯一的 bean 匹配,则使用该 bean 装配
- 如待装配的类型对应的 bean 在 IOC 容器中有多个,则使用待装配的属性的属性名作为 id 值再进行查找, 找到就装配,找不到就抛异常
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class UserService {
public void hi(){
System.out.println("UserService hi()~");
}
}
public class UserAction {
private UserService userService;
public void sayOk(){
System.out.println("UserAction.userService= " + userService);
userService.hi();
}【注意】
- 如果没有加@AutoWired注解,是不能装配到userService的
- 加上@AutoWired注解后,如果ioc容器中只有一个UserService的bean,那么直接将该bean装配
- 如果ioc容器有多个UserService的bean,那么就根据
userService去查找,如果找到则装配,找不到抛出异常
@AutoWired可以搭配@Qualifier使用
1
2
3
4
//指定 id=userService02 的 UserService 对象进行组装
//等价于@Resource(name = "userService")@Resource
规则说明:
- @Resource 有两个属性是比较重要的,分是 name 和 type,Spring 将@Resource 注解的name 属性解析为 bean 的名字,而 type 属性则解析为 bean 的类型.所以如果使用 name 属性,则使用 byName 的自动注入策略,而使用 type 属性时则使用 byType 自动注入策略
- 如果@Resource 没有指定 name 和 type ,则先使用byName注入策略, 如果匹配不上,再使用 byType 策略, 如果都不成功,就会报错
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class UserService {
public void hi(){
System.out.println("UserService hi()~");
}
}
public class UserAction {
//通过name注入,name即为ioc容器中配置的id,注解方式配置的即为类名首字母小写
//通过type注入
//@Resource(type = UserService.class)
private UserService userService;
public void hello(){
System.out.println("say hello...");
userService.hi();
}
}【说明】:不管是@AutoWired还是@Resource都保证属性名规范写法(即类名首字母小写)就可以注入
泛型依赖注入
在继承关系复杂情况下,传统方法是将 PhoneDao /BookDao 自动装配到BookService/PhoneSerive 中,当这种继承关系多时,就比较麻烦,而泛型依赖注入可以简化bean的装配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37public class Book {}
public class Phone {}
public abstract class BaseDao<T> {
public abstract void save();
}
public class BookDao extends BaseDao<Book> {
public void save() {
System.out.println("BookDao 的 save()");
}
}
public class PhoneDao extends BaseDao<Phone> {
public void save() {
System.out.println("PhoneDao 的 save()");
}
}
public class BaseService<T> {
private BaseDao<T> baseDao;
public void save() {
baseDao.save();
}
}
public class BookService extends BaseService<Book> {}
public class PhoneService extends BaseService<Phone> {}通过以上所示的泛型依赖注入,就可以在BookService中装配到BookDao对象
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 H-Loong!
评论
ValineDisqus



