Spring的一个核心理念就是依赖注入(dependency injection-DI)和控制反转(Inversion of Control-IoC),这两个概念是等同的,指的是容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖。
一、 组件类注解
@Component: 没有标准的角色
@Service: 标注一个业务逻辑组件类
@Repostory: 标注一个数据访问层(DAO)组件类
@Controller: 标注一个控制器组件类,通常在展现层(MVC->Spring MVC)使用
这四个注解本质上来说属于同一类注解,区别在于标志组件的类型。
@Component可以代替另外三个注解,因为这三个注解是被@Component标注的(不建议这么使用)。
注意以下几点:
1.使用@Service等几个注解声明当前类是Spring管理的一个Bean,Spring会自动创建相应的BeanDefinition对象,并注册到ApplicationContext中,这些类就成了Spring受管组件。
2.指定了某些类作为Spring Bean类使用后,还需要指定Spring的文件搜索路径,该路径下及其递归子包中所有的类都会被处理。
3.自动检测后扫描到的类,容器会将类名且第一个字母小写来作为bean的id,当然也可以指定类的名称,尤其是在一个接口有多个实现类的时候,要指定对应的类名搭配@Qualifier注解。
4.尽量使用对应组件注解的类替换@Component注解,在Spring未来的版本中,@Controller,@Service, @Repostory会携带更多语义,而且有利于开发和维护。
二 、装配Bean时的注解
备注:构成应用程序主干并由Spring IoC容器管理的对象称为bean,简单来说bean是瘦spring容器管理的对象。
@Autowired: Spring提供的注解
@Inject: JSR-330提供的注解
@Resource: JSR-250提供的注解
这三个都可以注解在set方法或者属性上,一般都是注解在属性上,优点是代码更少,层次更清晰。
注意:
@Inject和@Autowired在大多数场景下都是可以相互替换的,没有太大差别。
@Resource和@Autowired的作用类似,均可标注在字段或属性的setter方法上,但是由于提供方不一样,@Resource需要JDK1.6以上的版本。并且,@Autowired只按照byType自动注入,@Resource默认是byName自动注入,也可以按照byType注入。
由于@Autowired默认按照类型注入,如果容器中饱含多个同一类型的Bean,那么启动容器时就会报找不到指定类型bean的异常。解决的方法是结合@Qualifier注解来限定注入bean的名称。
@Resource中有两个重要的属性:name和type。name指定byName,如果没有指定name属性,当注解标注在字段上,即默认取字段名作为bean名称寻找依赖对象。如果注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找对象。如果@Resource没有指定name属性,且按照默认的名称仍然找不到依赖对象时,@Resource注解会回退到byType来自动注入。而一旦指定了name属性,就只能按照名称装配了。
三 Java配置
Java配置是通过@Configuration和@Bean来实现的。
@Configuration: 声明当前类是一个配置类,相当于一个Spring配置的xml文件中的<beans>
。
@Bean: 注解在方法上,声明当前方法的返回值为一个Bean
@Configuration
@ComponentScan({"com.example.demo"})
public class Config {
public Config(){
System.out.println("Config容器化初始化");
}
@Bean
public Person person(){
return new Person();
}
}
这里的配置文件和下面的xml中配置的是一样的
<beans>
<bean name="boy" class="com.example.demo.Boy" scope="singleton"></bean>
</beans>
注意:
@Bean注解在返回实例的方法上,如果未通过@Bean指定bean的名称,则默认与标注的方法名相同
@Bean默认为单例singleton作用域,可以通过@Scope(“prototype”)设置为原型作用域。也可以同时指定初始化和销毁方法。