1、Bean基础配置
Spring除了上一篇提到的xml配置文件进行配置之外,还可以使用注解方式进行配置,注解方式慢慢称为xml配置的替代方案。我们有了xml开发的经验,学习注解开发就方便了许多,注解方式更加快捷方便。
以前在xml中配置bean:
<bean id="" name="" class=""></bean>
现在可以使用@Component
来代替<bean>
啦,被@Component
注解标识的类,会在指定扫描范围内被Spring加载并实例化
@Component(value = "userDao")
public class UserDaoImpl implements UserDao {
// value可省略
// 如果不为该类设置 beanName的话,默认是该类的类名,且首字母小写
}
<?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/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 注解组件扫描: 扫描指定的基本包及其子包下的类有无注解 -->
<context:component-scan base-package="com.yao"></context:component-scan>
</beans>
ApplicationContext context = new ClassPathXmlApplicationContext("anno.xml");
Object userDao = context.getBean("userDao");
为什么@Component能够代替<bean>来进行配置呢?
- 也是通过Spring的对外扩展点,即Spring的后处理器
1、常用的<bean>中的属性
xml配置 | 注解 | 描述 |
---|---|---|
<bean scope=""> | @Scope("singleton") | 在类上 或 使用了@Bean标注的方法上,标注Bean的作用范围,取值为 singleton 或 prototype |
<bean lazy-init=""> | @Lazy(true) | 在类上 或 使用了@Bean标注的方法上,标注Bean是否延迟加载,取值为 true 或 false |
<bean init-method=""> | @PostConstruct | 在方法上使用,标注Bean的实例化后执行的方法 |
<bean destroy-method=""> | @PreDestroy | 在方法上使用,标注Bean的销毁前执行的方法 |
2、@Component衍生的3个注解
由于JavaEE开发是分层的,为了每层的Bean的注解语义更明确,衍生出如下3个注解:
注解 | 描述 |
---|---|
@Repository | 在Dao层类上使用 |
@Service | 在Service层类上使用 |
@Controller | 在Web层类上使用 |
3个注解的使用方式与 @Component 如出一辙。如果有类不属于这三层,又想要交由Spring容器管理,直接使用@Component即可。
2、Bean依赖注入
之前在xml配置中,想要注入属性:
<bean id="" class="">
<property name="" value=""></property>
<property name="" ref=""></property>
</bean>
有如下几个注解用于在Bean内部进行属性注入:
注解 | 描述 |
---|---|
@Value | 使用在字段或方法上,用于注入普通属性 |
@Autowired | 使用在字段或方法上,用于注入引用属性 (通过类型注入) |
@Qualifier | 使用在字段或方法上,可以结合@Autowired,根据名称注入 |
@Resource | 使用在字段或方法上,根据类型或名称进行注入 |
有几个需要注意的地方:
- 在Bean中甚至可以没有set方法,因为Spring直接通过反射来给这个字段或方法通过
反射
强制赋值- @Autowired根据类型注入。如果同一个类型的Bean有多个,尝试根据名字(类名首字母小写) 进行二次匹配,匹配不成功才会报错;如果想要指定名称注入,则下面再加个@Qualifier(“beanName”) 来组合使用
- @Resource也通过类型去注入属性。不指定名称参数时,按类型注入,跟@Autowired没区别;指定名称就按名称注入
- @Autowired用在有参方法时,如果方法参数的bean在容器中配置了,就可以实现自动注入;如果方法参数是集合类型,且其泛型就是在容器中已配置的bean,而且该类型的bean在容器中已经存在多个,那么这些所有相同类型的bean都会被注入到该集合中来
- @Qualifier(“beanName”)可以用作在方法参数上注入。在方法参数前使用该注解前面不需要加@Autowired,而只需@Qualifier(“beanName”)指定bean的名称即可完成注入
其他注解
注解 | 描述 |
---|---|
@Primary | 指定当前Bean的实例在通过类型注入时优先返回 |
@Profile(“环境名”) | 切换环境加载该bean,没有加该注解的bean则默认是存在公共环境下的 |
3、非自定义的bean注解开发
非定义Bean不能用@Component进行管理,非定义Bean要通过工厂的方式进行实例化,这时使用@Bean
注解即可
@Bean的属性为beanName,如果不指定则为当前方法的名称,且方法所在的类必须被Spring管理才能正常配置
@Bean("datasource")
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/?");
dataSource.setUsername("");
dataSource.setPassword("");
return dataSource;
}
4、Bean的配置类注解开发
用来完全替代xml文件的配置,使用类的方式完成这些配置。对应的注解是@Configuration
,标注当前类是一个配置类
@Configuration
@ComponentScan("com.yao")
@PropertySource({"classpath:jdbc.properties", "XXX.xx"})
@Import(JdbcConfig.class)
// 包扫描、加载配置文件(多个)、导入配置类(该类不能使用其他注解,才能成功导入进来并成为配置类的一部分)
public class SpringConfig {
}
同时,我们获取容器的方法也需要发生变化
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
Object userDao = context.getBean("userDao");