注:本文部分内容参考https://blog.csdn.net/ncepu_Chen/article/details/91903396#_454
文章目录
依赖注入的三种数据类型
1.String与其他基本数据类型
2.其他bean类型
3.复杂类型/集合类型
依赖注入三种方式
1.构造函数注入
使用的标签:·<constructor-arg>
用来定义构造函数的参数,其属性可大致分为两类:
1. 指定给哪个参数赋值:
index: 指定参数在构造函数参数列表的索引位置
type: 指定参数在构造函数中的数据类型
name: 指定参数在构造函数中的变量名,最常用的属性
2. 指定赋给字段的值
value: 给基本数据类型和String类型赋值
ref: 给其它Bean类型的字段赋值,ref属性的值应为配置文件中配置的Bean的id
类结构如下:
public class AccountServiceImpl implements IAccountService {
//如果是经常变化的数据,并不适用于注入的方式
private String name;
private Integer age;
private Date birthday;
public AccountServiceImpl(String name, Integer age, Date birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
}
xm文件配置如下:
<bean id="accountService" class="cn.maoritian.service.impl.AccountServiceImpl">
<constructor-arg name="name" value="myname"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<!--使用Date类的无参构造函数创建Date对象-->
<bean id="now" class="java.util.Date" scope="prototype"></bean>
缺点: 如果在创建对象时用不到某个参数,我们也必须提供。所以此方法不常用!
2.Set方法注入(常用)
在类中提供需要注入成员属性的set方法,创建对象只调用要赋值属性的set方法.
涉及的标签:
属性:
name:要调用set方法名称
value: 给基本数据类型和String类型赋值
ref: 给其它Bean类型的字段赋值,ref属性的值应为配置文件中配置的Bean的id
public class AccountServiceImpl implements IAccountService {
private String name;
private Integer age;
private Date birthday;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public void saveAccount() {
System.out.println(name+","+age+","+birthday);
}
}
<!-- 使用Date类的无参构造函数创建Date对象 -->
<bean id="now" class="java.util.Date" scope="prototype"></bean>
<bean id="accountService" class="cn.maoritian.service.impl.AccountServiceImpl">
<property name="name" value="myname"></property>
<property name="age" value="21"></property>
<!-- birthday字段为已经注册的bean对象,其id为now -->
<property name="birthday" ref="now"></property>
</bean>
3.使用注解实现
将注解写在类的定义之中,首先将bean.xml文件的最开始部分换成如下代码,并使用context标签
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--告知spring在创建容器时要扫描的包-->
<context:component-scan base-package="com.itheima"></context:component-scan>
常用注解
一个bean标签如下:
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"
scope="" init-method="" destroy-method="">
<property name="" value="" ref=""></property>
</bean>
用于创建对象的注解
1.@Component
他的作用就和在xml配置文件中编写一样,将此类对象存入spring容器中,
属性: value:用于指定bean的id,若不指定,bean的id就是当前类名,并且首字母小写。
2.@Controller: 将当前表现层对象存入spring容器中
3.@Service: 将当前业务层对象存入spring容器中
4.@Repository: 将当前持久层对象存入spring容器中
以上三个与component一样!
例子:
@Component
public class AccountServiceImpl implements IAccountService{
}
//main文件
//1.获取核心容器对象,此方法构建容器时,对象立即加载,用的多!
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
//2.根据id获取bean对象
IAccountService as =(IAccountService) ac.getBean("accountService");
用于注入对象的注解
相当于bean
标签的<property>
标签
1.@Autowired
: 自动按照成员变量类型注入.
注入过程
当spring容器中有且只有一个对象的类型与要注入的类型相同时,注入该对象.
当spring容器中有多个对象类型与要注入的类型相同时,使用要注入的变量名作为bean的id,在spring 容器查找,找到则注入该对象.找不到则报错.
出现位置: 既可以在变量上,也可以在方法上
细节: 使用注解注入时,set方法可以省略
2.@Qualifier
: 在自动按照类型注入的基础之上,再按照bean的id注入.
出现位置: 既可以在变量上,也可以在方法上.注入变量时不能独立使用,必须和@Autowire
一起使用; 注入方法时可以独立使用.
属性:
value
: 指定bean的id
3.@Resource
: 直接按照bean的id注入,它可以独立使用.独立使用时相当于同时使用@Autowired
和@Qualifier
两个注解.
属性:
name
: 指定bean的id
4.@Value
: 注入基本数据类型和String类型数据
属性:
value
: 用于指定数据的值,可以使用el表达式(${表达式})
用于改变作用范围的注解
这些注解的作用相当于bean.xml中的标签的scope属性.
@Scope
: 指定bean的作用范围
属性:
value
: 用于指定作用范围的取值,“singleton”,“prototype”,“request”,“session”,“globalsession”
和生命周期相关的注解
这些注解的作用相当于bean.xml中的标签的init-method和destroy-method属性
@PostConstruct
: 用于指定初始化方法
@PreDestroy
: 用于指定销毁方法
实例(基于XML的IOC案例)
1.创建数据库
create table account(
id int primary key auto_increment,
name varchar(40),
money float
)character set utf8 collate utf8_general_ci;
insert into account(name,money) values('aaa',1000);
insert into account(name,money) values('bbb',1000);
insert into account(name,money) values('ccc',1000);
2.文件结构
3.接口代码
IAccountDao
public interface IAccountDao {
/**
* 查询所有
* @return
*/
List<Account> findAllAccount();
/**
* 查询一个
* @return
*/
Account findAccountById(Integer accountId);
/**
* 保存
* @param account
*/
void saveAccount(Account account);
/**
* 更新
* @param account
*/
void updateAccount(Account account);
/**
* 删除
* @param accountId
*/
void deleteAccount(Integer accountId);
}
IAccountService
public interface IAccountService {
/**
* 查询所有
* @return
*/
List<Account> findAllAccount();
/**
* 查询一个
* @return
*/
Account findAccountById(Integer accountId);
/**
* 保存
* @param account
*/
void saveAccount(Account account);
/**
* 更新
* @param account
*/
void updateAccount(Account account);
/**
* 删除
* @param accountId
*/
void deleteAccount(Integer accountId);
}
4.实现类代码
AccountDaoImpl
public class AccountDaoImpl implements IAccountDao {
private QueryRunner runner;
public void setRunner(QueryRunner runner) {
this.runner = runner;
}
public List<Account> findAllAccount() {
try{
return runner.query("select * from account", new BeanListHandler<Account>(Account.class));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Account findAccountById(Integer accountId) {
try{
return runner.query("select * from account where id = ?", new BeanHandler<Account>(Account.class),accountId);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void saveAccount(Account account) {
try{
runner.update("insert into account(name, money) values(?,?)", account.getName(),account.getMoney());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void updateAccount(Account account) {
try{
runner.update("update account set name = ?, money = ? where id = ?", account.getName(),account.getMoney(),account.getId());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void deleteAccount(Integer accountId) {
try{
runner.update("delete from account where id = ?", accountId);
} catch (Exception e) {
throw new RuntimeException(e);
}
AccountServiceImpl
public class AccountServiceImpl implements IAccountService {
private IAccountDao accountDao;
public void setAccountDao(IAccountDao accountDao) {
this.accountDao = accountDao;
}
public List<Account> findAllAccount() {
return accountDao.findAllAccount();
}
public Account findAccountById(Integer accountId) {
return accountDao.findAccountById(accountId);
}
public void saveAccount(Account account) {
accountDao.saveAccount(account);
}
public void updateAccount(Account account) {
accountDao.updateAccount(account);
}
public void deleteAccount(Integer accountId) {
accountDao.deleteAccount(accountId);
}
}
5.账户实体类
Account
public class Account implements Serializable {
private Integer id;
private String name;
private Float money;
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setMoney(Float money) {
this.money = money;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public Float getMoney() {
return money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
6.测试类代码
AccountServiceTest
public class AccountServiceTest {
@Test
public void testFindAll() {
// 1.获取容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
// 2.得到业务层对象
IAccountService iAccountService = applicationContext.getBean("accountService",IAccountService.class);
// 3.执行方法
List<Account> accounts = iAccountService.findAllAccount();
for (Account account : accounts) {
System.out.println(account);
}
}
@Test
public void testFindOne() {
// 1.获取容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
// 2.得到业务层对象
IAccountService iAccountService = applicationContext.getBean("accountService",IAccountService.class);
// 3.执行方法
Account account = iAccountService.findAccountById(1);
System.out.println(account);
}
@Test
public void testSave() {
Account account = new Account();
account.setName("test");
account.setMoney(12345f);
// 1.获取容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
// 2.得到业务层对象
IAccountService iAccountService = applicationContext.getBean("accountService",IAccountService.class);
// 3.执行方法
iAccountService.saveAccount(account);
}
@Test
public void testUpdate() {
// 1.获取容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
// 2.得到业务层对象
IAccountService iAccountService = applicationContext.getBean("accountService",IAccountService.class);
// 3.执行方法
Account account = iAccountService.findAccountById(4);
account.setMoney(23456f);
iAccountService.updateAccount(account);
}
@Test
public void testDelete() {
// 1.获取容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
// 2.得到业务层对象
IAccountService iAccountService = applicationContext.getBean("accountService",IAccountService.class);
// 3.执行方法
iAccountService.deleteAccount(4);
}
}
bean.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- -->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<property name="accountdao" ref="accountDao"></property>
</bean>
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
<property name="runner" ref="runner"></property>
</bean>
<bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
<constructor-arg name="ds" ref="dataSource"></constructor-arg>
</bean>
<!--配置数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/eesy"></property>
<property name="user" value="root"></property>
<property name="password" value="123456"></property>
</bean>
</beans>