一, 引言
最近因为找工作, 导致很长时间没有更新, 找工作的时候你会明白浪费的时间后面都是要还的, 现在的每一点努力, 将来也会给你回报的, 但行好事, 莫问前程! 努力总不会有错的.
上一篇 spring 的配置博客评论中有园友指出现在很少用 xml 类配置 SpringBean 了, 都是用注解的方式来进行配置, 那么这篇就来讲注解配置.
使用. xml 文件来对 bean 进行注入的缺点很明显: 文件会十分庞大, 如果分多模块去配置, 文件又特别的多, 这些会导致可读性和可维护性变差.
为了解决这两个问题, Spring 引入了注解, 通过 "@XXX" 的方式, 让注解与 Java Bean 紧密结合, 既大大减少了配置文件的体积, 又增加了 Java Bean 的可读性与内聚性.
二, 将对象注册到容器
注解如何使用呢, 分为三步
第一步: 在 applicationContext.xml 中引入命名空间
第二步: 在 applicationContext.xml 文件中引入注解扫描器
<context:component-scan base-package="com.yuanqinnan.test"></context:component-scan>
base-package: 表示含有注解类的包名
如果扫描多个包, 则上面的代码书写多行, 改变 base-package 里面的内容即可!
如果使用 Idea 引入注解扫描器, 就会直接引入命名空间
第三步: 在 Car 类中添加注解 @Component
- @Component
- public class Car {
- private String Color;
- public String getColor() {
- return Color;
- }
- public void setColor(String color) {
- Color = color;
- }
- @Override
- public String toString() {
- return "Car{" +
- "Color='" + Color + '\'' +
- '}';
- }
- }
第四步: 测试
- ApplicationContext ctx=new ClassPathXmlApplicationContext("META-INF/applicationContext.xml");
- // 获取 bean 的实例
- Car car=(Car) ctx.getBean("car");
- System.out.println(car.toString());
结果: Car{Color='null'}
三, 值类型注入
- @Value("yellow")
- public void setColor(String color) {
- Color = color;
- }
结果: Car{Color='yellow'}
四, 引用类型注入
引用类型分为自动装配 @Autowired 和手动注入 @Resource
4.1 @Autowired
顾名思义, 就是自动装配, 其作用是为了消除代码 Java 代码里面的 getter/setter 与 bean 属性中的 property. 当然, getter 看个人需求, 如果私有属性需要对外提供的话, 应当予以保留.
@Autowired 默认按类型匹配的方式, 在容器查找匹配的 Bean, 当有且仅有一个匹配的 Bean 时, Spring 将其注入 @Autowired 标注的变量中.
创建一个新类 Boss
- @Component
- public class Boss {
- // 自动装配
- @Autowired
- private Car car;
- private String name;
- @Value("袁帅")
- public void setName(String name) {
- this.name = name;
- }
- public String getName() {
- return name;
- }
- @Override
- public String toString() {
- return "Boss{" +
- "car=" + car.getColor() +
- ", name='" + name + '\'' +
- '}';
- }
- }
测试:
- Boss boss=(Boss)ctx.getBean("boss");
- System.out.println(boss.toString());
结果: Boss{car=yellow, name='袁帅'}
这种方式存在匹配到多个类型一致的的情况, 这种情况需要 Qualifier 来解决
定义一个 Car 接口:
- public interface ICar {
- String getCarName();
- }
两个实现类 BMWCar 和 BenzCar:
- @Component("benzCar")
- public class BenzCar implements ICar {
- @Override
- public String getCarName() {
- return "奔驰";
- }
- }
- @Component("bmwCar")
- public class BMWCar implements ICar {
- @Override
- public String getCarName() {
- return "宝马";
- }
- }
工厂类:
- @Component("cf")
- public class CarFactory {
- @Autowired
- private ICar iCar;
- public String toString(){
- return iCar.getCarName();
- }
- }
很明显这种写法会报错,
No unique bean of type [com.spring.service.ICar] is defined: expected single matching bean but found 2: [bmwCar, benz]
很明显这种写法会报错, 因为 Spring 并不知道应当引用哪个实现类, 这个时候使用 @Qualifie
- @Autowired
- @Qualifier("bmwCar")
- private ICar iCar;
结果: 宝马
4.2 @Resource
@Resource 注解与 @Autowired 注解作用非常相似, 这个就简单说了, 看例子:
- @Resource(type = BenzCar.class)
- private ICar iCar2;
- @Resource(name = "benzCar")
- private ICar iCar3;
五, 常用注解总结
最后介绍常用的注解
@Configuration 把一个类作为一个 IoC 容器, 它的某个方法头上如果注册了
@Bean, 就会作为这个 Spring 容器中的 Bean.
@Scope 注解 作用域 @Lazy(true) 表示延迟初始化
@Service 用于标注业务层组件,
@Controller 用于标注控制层组件 (如 struts 中的 action)
@Repository 用于标注数据访问组件, 即 DAO 组件.
@Component 泛指组件, 当组件不好归类的时候, 我们可以使用这个注解进行标注.
@Scope 用于指定 scope 作用域的 (用在类上)
@PostConstruct 用于指定初始化方法 (用在方法上)
@PreDestory 用于指定销毁方法 (用在方法上)
@DependsOn: 定义 Bean 初始化及销毁时的顺序
@Primary: 自动装配时当出现多个 Bean 候选者时, 被注解为 @Primary 的 Bean 将作为首选者, 否则将抛出异常 @Autowired 默认按类型装配, 如果我们想使用按名称装配, 可以结合 @Qualifier 注解一起使用. 如下:@Autowired @Qualifier("personDaoBean") 存在多个实例配合使用 @Resource 默认按名称装配, 当找不到与名称匹配的 bean 才会按类型装配.
@PostConstruct 初始化注解
@PreDestroy 摧毁注解 默认 单例 启动就加载
@Async 异步方法调用
来源: https://www.cnblogs.com/yuanqinnan/p/10503859.html