spring中bean的自动装配和作用域

时间:2021-06-29 19:06:05

在上一节《Spring依赖注入(dependency injection)》我们讲了spring注入的几种方式:构造器注入、set注入、p命名空间注入和c命名空间注入,今天我们来说一下自动装配---autowire。

自动转配是可以简化spring的配置文件。


1、byName装配


新建一个java项目,结构如图:


spring中bean的自动装配和作用域

接口类UserDao代码:


package com.my.spring.dao;

public interface UserDao {

public void getUser() ;

}


接口实现类UserDaoMySqlImpl代码:


package com.my.spring.dao.impl;

import com.my.spring.dao.UserDao;

public class UserDaoMySqlImpl implements UserDao{

@Override
public void getUser() {
System.out.println("MySql获取用户数据");
}

}


UserDaoOracleImpl代码:


package com.my.spring.dao.impl;

import com.my.spring.dao.UserDao;

public class UserDaoOracleImpl implements UserDao{

@Override
public void getUser() {
System.out.println("Oracle获取用户数据");
}

}


UserService接口类代码:


package com.my.spring.service;

public interface UserService {

public void getUser() ;

}


实现类UserServiceImpl代码:


package com.my.spring.service.impl;

import com.my.spring.dao.UserDao;
import com.my.spring.service.UserService;

public class UserServiceImpl implements UserService{

private UserDao userDao = null ;

public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}

@Override
public void getUser() {
userDao.getUser() ;
}

}

beans.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="userDao" class="com.my.spring.dao.impl.UserDaoMySqlImpl" />

<!-- autowire:自动装配 简化spring配置
byName:根据bean对应的class中的属性对应的set方法名称在beans.xml中找到相应的bean,
如果有则装配上;没有则不装配。
-->
<bean id="service" class="com.my.spring.service.impl.UserServiceImpl"
autowire="byName">
</bean>


</beans>

其中Service的bean使用的是自动装配byName,对应的类UserServiceImpl中的关系如图:


spring中bean的自动装配和作用域


右边service对应的bean中的类中属性有一个setUserDao()方法,这个setUserDao()方法去掉set后,剩下是的userDao,然后到右边的beans.xml配置中寻找id是userDao的bean,如果找了,就对应装配成这个bean的class,如果找不到,就不装配。


测试类Test代码:


package com.my.spring.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.my.spring.service.UserService;


public class Test {

public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml") ;
UserService us = (UserService) ac.getBean("service") ;
us.getUser() ;
}

}


运行结果在控制台打印如图:


spring中bean的自动装配和作用域



为了解决在beans.xml中的每一个bean后面都配置autowire,所以还有一种简便写法,就是在头文件处写default-autowire="byName"  如图:


spring中bean的自动装配和作用域


2、byType装配

byType(不建议使用):根据类型进行自动装配,不用管bean的id . 但是同一种类型的bean只能有一个;


beans.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="mysqlDao" class="com.my.spring.dao.impl.UserDaoMySqlImpl" />
<bean id="oracleDao" class="com.my.spring.dao.impl.UserDaoMySqlImpl" />

<!-- autowire:自动装配 简化spring配置
byName:根据bean对应的class中的属性对应的set方法名称在beans.xml中找到相应的bean,
如果有则装配上;没有则不装配;
byType(不建议使用):根据类型进行自动装配,不用管bean的id . 但是同一种类型的bean只能有一个;
-->
<bean id="service" class="com.my.spring.service.impl.UserServiceImpl"
autowire="byType">
</bean>


</beans>

在上面这个配置文件中,有两个UserDao的实现类,如果是这种情况,运行测试类Test,就会报错,因为有两个UserDao的实现类,容器不知道找那个,所以这种很容易出现错误,建议慎用!!!

如果想运行正常,只能存在一个UserDao的实现类。


3、constructor装配


其他代码不变,UserServiceImpl代码中去掉了set方法,增加了构造方法,代码如:


package com.my.spring.service.impl;

import com.my.spring.dao.UserDao;
import com.my.spring.service.UserService;

public class UserServiceImpl implements UserService {

private UserDao userDao = null;

public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}


public void getUser() {
userDao.getUser();
}

}


beans.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="mysqlDao" class="com.my.spring.dao.impl.UserDaoMySqlImpl" />
<!-- <bean id="oracleDao" class="com.my.spring.dao.impl.UserDaoMySqlImpl" /> -->

<!-- autowire:自动装配 简化spring配置
byName:根据bean对应的class中的属性对应的set方法名称在beans.xml中找到相应的bean,
如果有则装配上;没有则不装配;
byType(不建议使用):根据类型进行自动装配,不用管bean的id . 但是同一种类型的bean只能有一个;
constructor:当通过构造器 实例化bean时 适用byType的方式 装配构造方法
-->
<bean id="service" class="com.my.spring.service.impl.UserServiceImpl"
autowire="constructor">
</bean>


</beans>


二、作用域


spring中bean的自动装配和作用域


注意:在整合struts2和spring时,需要将Action设为scope=“prototype”