三种方法装配bean
1.自动化装配bean
1.1 bean之间没有依赖关系
配置类:
@Configuration //表明这是一个配置类,配置Spring容器
@ComponentScan //启动组件扫描,默认会扫描与配置类相同的包
public class LtConfig {
}
UserDaoImpl:
@Component //表明该类会作为组件类,并告知Spring要为这个类创建bean
public class UserDaoImpl implements UserDao {
public void getUser() {
System.out.println("默认获取用户的数据");
}
}
测试:
public class MyTest { //测试类
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(com.lt.LtConfig.class);
UserDao dao = (UserDao) context.getBean("userDaoImpl");
dao.getUser();
}
}
1.2 bean之间存在依赖
配置类不变
CarDaoImpl:
@Component
public class CarDaoImpl implements CarDao{
@Override
public void getCarName() {
System.out.println("AE86");
}
}
UserDaoImpl:
@Component
public class UserDaoImpl implements UserDao {
private CarDao carDao;
@Autowired
public UserDaoImpl(CarDaoImpl carDao){
this.carDao = carDao;
}
@Override
public void getUser() {
System.out.println("获得用户");
carDao.getCarName();
}
}
UserDaoImpl对CarDaoImpl产生了依赖,并通过构造器注入。在这里,使用@Autowired由Spring容器来自动装配。在这里@Autowired用在了构造方法上。实际上,@Autowired注解可以用在类的任何方法上,甚至不需要声明用于装配的方法,直接用在声明的变量上也可以。如:
@Component
public class UserDaoImpl implements UserDao {
@Autowired
private CarDao carDao;
@Override
public void getUser() {
System.out.println("获得用户");
carDao.getCarName();
}
}
运行结果:

如果没有匹配的bean,那么在应用上下文创建的时候,Spring会抛出一个异常。为了避免异常的出现,可以将@Autowired 的 required属性设置为 false:@Autowired(required=false),此时,Spring会尝试执行自动装配,但是如果没有匹配的bean的话,Spring将会让这个bean处于未装配的状态。
2.通过Java代码装配bean
2.1 bean之间没有依赖关系
配置类:
@Configuration
public class LtConfig {
@Bean(name="userDao")
public UserDaoImpl userDaoImpl(){
return new UserDaoImpl();
}
}
创建 JavaConfig 类的关键在于为其添加@Configuration 注解,@Configuration 注解表明这个类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。
@Bean 注解会告诉Spring这个方法将会返回一个对象,该对象要注册为Spring应用上下文的 bean 。方法体中包含了最终产生 bean 实例的逻辑。默认情况下,bean 的 id 与带有 @bean 注解的方法名是一样的,也可以通过 name 属性指定一个名字。
UserDaoImpl:
public class UserDaoImpl implements UserDao{
public void show(){
System.out.println("调用show方法");
}
}
测试:
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(com.lt.LtConfig.class);
UserDao userDao = (UserDao) context.getBean("userDao");
userDao.show();
}
}
2.2 bean之间存在依赖
方法一:
UserDaoImpl:
public class UserDaoImpl implements UserDao{
private CarDao carDao;
public UserDaoImpl(CarDaoImpl carDaoImpl){
this.carDao = carDaoImpl;
}
public void show(){
System.out.println("调用show方法");
carDao.getCarName();
}
}
CarDaoImpl:
public class CarDaoImpl implements CarDao {
@Override
public void getCarName() {
System.out.println("AE86");
}
}
配置类:
@Configuration
public class LtConfig {
@Bean
public CarDaoImpl carDaoImpl(){
return new CarDaoImpl();
}
@Bean(name="userDao")
public UserDaoImpl userDaoImpl(){
return new UserDaoImpl(carDaoImpl());
}
}
CarDaoImpl的配置方法与之前的相同,UserDaoImpl稍微有些变化,在这里没有用默认的无参构造器来构建实例,而是调用了需要传入依赖对象的构造器来创建实例。看起来依赖对象是通过调用 carDaoImpl() 方法得到的,事实并非完全如此,因为 carDaoImpl() 方法上添加了@bean 注解,Spring将会拦截所有对它的调用,并确保直接返回该方法所创建的 bean,而不是每次都对其进行实际的调用。
如果调用方法来引用bean的方式让你感到困惑,那么下面还有一种理解起来更为简单的方式:
@Configuration
public class LtConfig {
@Bean
public CarDaoImpl carDaoImpl(){
return new CarDaoImpl();
}
@Bean(name="userDao")
public UserDaoImpl userDaoImpl(CarDaoImpl carDao){
return new UserDaoImpl(carDao);
}
}
这种方法把依赖的bean作为参数传递进来。当Spring调用userDaoImpl创建bean的时候,它会自动装配一个CarDaoImpl到配置方法之中。通过这种方式引用其他的bean通常是最佳的选择,因为它不会要求将CarDaoImpl和UserDaoImpl声明到同一个配置类中,甚至没有要求CarDaoImpl必须要在JavaConfig中声明。
我们可以进行测试:
UserDaoImpl:
public class UserDaoImpl implements UserDao{
private CarDao carDao;
public UserDaoImpl(CarDaoImpl carDaoImpl){
this.carDao = carDaoImpl;
}
public void show(){
System.out.println("调用show方法");
carDao.getCarName();
}
public CarDao getCarDao(){ //获得carDao对象
return carDao;
}
}
配置类:
@Configuration
public class LtConfig {
@Bean("carDao")
public CarDaoImpl carDaoImpl(){
return new CarDaoImpl();
}
@Bean(name="userDao")
public UserDaoImpl UserDaoImpl(){
return new UserDaoImpl(carDaoImpl());
}
@Bean(name="userDao2")
public UserDaoImpl UserDaoImpl2(){
return new UserDaoImpl(carDaoImpl());
}
}
在配置类中,我们增加了一个方法用来创建 uerDao2,创建方法和创建 userDao 完全一样。下面看看结果。
测试:
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(com.lt.LtConfig.class);
UserDao userDao = (UserDao) context.getBean("userDao");
// userDao.show();
UserDao userDao2 = (UserDao) context.getBean("userDao2");
CarDao carDao = (CarDao) context.getBean("carDao");
System.out.println("三个carDao对象相同吗?"+(carDao==userDao.getCarDao()&&userDao.getCarDao()==userDao2.getCarDao()));
System.out.println("两个userDao对象相同吗?"+(userDao==userDao2));
}
}
测试结果:

结果表明:两个 userDao 中的 carDao 指向相同且都指向 carDao,但两个 userDao 指向不同。
3. 通过XML装配bean
这种装配bean的方法是最简单也是最好理解的,在此不过多阐述。
导入和混合配置
1. 在 JavaConfig 中引用 JavaConfig 配置
CarConfig.class
@Configuration
public class CarConfig {
@Bean("carDao")
public CarDaoImpl carDaoImpl(){
return new CarDaoImpl();
}
}
UserConfig.class
@Configuration
@Import(CarConfig.class)
public class UserConfig {
@Bean(name="userDao")
public UserDaoImpl UserDaoImpl(){
return new UserDaoImpl(carDaoImpl());
}
}
使用 @Import 注解可以导入 JavaConfig 类。
2. 在 JavaConfig 中引用 XML 配置
CarConfig.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="carDao" class="com.lt.dao.CarDaoImpl"/>
</beans>
UserConfig.class
@Configuration
@ImportResource("CarConfig.xml")
public class UserConfig {
@Bean(name="userDao")
public UserDaoImpl UserDaoImpl(CarDaoImpl carDao){
return new UserDaoImpl(carDao);
}
}
使用 @ImportResource 可以导入 XML 配置文件
3. 在 XML 配置中引用 XML 配置
CarConfig.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="carDao" class="com.lt.dao.CarDaoImpl"/>
</beans>
UserConfig.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="CarConfig.xml"/>
<bean id="userDao" class="com.lt.dao.UserDaoImpl">
<constructor-arg ref="carDao"/>
</bean>
</beans>
使用 import 标签可以导入 XML 配置文件
4. 在 XML 配置中引用 JavaConfig
CarConfig.class
@Configuration
public class CarConfig {
@Bean("carDao")
public CarDaoImpl carDaoImpl(){
return new CarDaoImpl();
}
}
UserConfig.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.lt.CarConfig" />
<bean id="userDao" class="com.lt.dao.UserDaoImpl">
<constructor-arg ref="carDao"/>
</bean>
</beans>
可以通过 bean 元素将 JavaConfig 导入进来。
浙公网安备 33010602011771号