一、引言
最近因为找工作,导致很长时间没有更新,找工作的时候你会明白浪费的时间后面都是要还的,现在的每一点努力,将来也会给你回报的,但行好事,莫问前程!努力总不会有错的。
上一篇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异步方法调用