文章目录
bean的自动创建和自动装配
@Component
: 标注一个类,spring会自动用默认无参的构造方法
自动创建一个bean,该bean的id默认为类名首字母小写,也可以用@Component(“xxx”)将bean的id设置成xxx
@ComponentScan
:标注一个类(一般该类都是配置类,即被@Configuration
标注的类),表示启用组件扫描,默认会扫描与配置类相同的包及这个包下的所有子包,查找带有@Component
注解的类,没有被扫描到@Component
不会自动创建bean。 可以用basePackages属性自定义要扫描的基础包
@Configuration
:标注一个类,把该类作为spring的配置类,该类可以替代xml配置文件。这个配置类其实就相当于spring 的一个xml配置文件
@Configuration
@ComponentScan(basePackages = "com.spring.*")
public class Hello {
//把Hello类当成配置类,并且启用组件扫描,扫描的路径为com.spring包及其子包
}
相当于xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.spring.*"/>
</beans>
@Autowired
:可以标注属性或者任意方法。如果标注的是属性,spring会在应用上下文中的所有bean(不论是自动创建还是在xml中声明)找到可以匹配的bean进行自动装配;如果标注的是方法,spring会尝试满足方法参数中的所有需要依赖。如果有多个满足的bean,spring会抛出异常
@Autowired
Hello hello;//自动找到类型为Hello或Hello子类的bean进行注入
@Autowired
public void test(Hello hello){
//@Autowired注解标注test方法,方法参数为Hello类型,spring会自动找到类型为Hello或Hello子类的bean进行注入到hello参数
this.hello = hello;
}
Named
:该注解由java注入规范提供,可用来替代spring的@Component注解,用法也一致。两者有细微差异,但绝大多数情况下可以相互代替
@Inject
:该注解有Java依赖规范提供,但spring也支持,使用方法和作用@Autowired
差不多,大多数情况下可以相互替代
通过Java代码新建bean
@Bean
: 标注一个方法。@Bean
注解会告诉spring,这个方法将会返回一个对象,该对象将要注册为spring应用上下文的一个bean。该bean的id默认与@Bean
所标注的方法名一致,但是也可以通过name属性指定一个新id。一般来说,现在的springboot项目也大多采用这种方法生成bean完成一些环境的配置 。另外,值得注意的是,@Bean
注解一般用在@Configuration
标注的配置类里,这样生成的bean就可以被spring容器统一管理。其实换个角度很好理解,配置类相当于xml配置文件,@Bean
相当于xml里的<bean>
标签。
@Configuration
public class Hello {
@Bean
//@Bean(name="manzuo") 也可以通过name属性为bean指定一个新的id
public Hello test(){
//将会新建一个类型为Hello,id为test的bean
return new Hello();
}
}
特别说明:默认情况下,spring中的bean都是单例的,所以spring会拦截@Bean
注解所标注的方法的调用并确保返回的是spring生成的bean。以上面的test()方法为例,通过@Bean
注解,spring会生成一个类型为Hello,id为test的bean。当其他方法调用test()方法时候,spring会拦截对test()调用,并直接返回之前spring生成的bean。这样就确保了该bean始终是单例的,而不是调用多少次test()方法就new多少个Hello对象。
消除自动装配的歧义
@Primary
: 通常和@Bean
或者 @Component
注解一起使用,将该bean设置成首选的。当使用@Autowired
自动装配的时候,如果遇到两个以上符合类型的bean的时候,spring会优先选择有@Primary
标注的bean;如果两个或者两个以上符合类型的bean都没有@Primary
注解标识,spring不会自动帮你选择其中一个bean进行自动注入,而是抛出异常提醒你。
@Qualifier
: 该注解有两个用途,
- 与
@Bean
或者@Component
一起使用可以为该bean创建一个自定义的限定符(默认情况下,bean的限定符和Bean的id一致)
public class Hello {
@Bean(name="manzuo")
@Qualifier("cool")
//spring 会创建一个 id为manzuo,限定符为cool的bean
public Hello test(){