目录
一、DI依赖注入
Spring提供了两种注入方式,分别是:
setter注入 简单类型 引用类型
构造器注入 简单类型 引用类型
1.setter注入
添加BookDao、BookDaoImpl、UserDao、UserDaoImpl、BookService和 BookServiceImpl类
public interface BookDao {
public void save();
}
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
public interface UserDao {
public void save();
}
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("user dao save ...");
}
}
public interface BookService {
public void save();
}
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
xml文件
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
运行文件
public class AppForLifeCycle {
public static void main( String[] args ) {
ApplicationContext ctx = new
ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookService = (BookService) ctx.getBean("bookService");
bookService.save();
}
}
1.1setter引用类型注入
在BookServiceImpl中声明userDao属性,并提供setter方法
public class BookServiceImpl implements BookService {
private BookDao bookDao;
private UserDao userDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
userDao.save();
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
在applicationContext.xml配置文件中使用property标签注入
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
<property name="userDao" ref="userDao"/>
</bean>
1.2setter简单类型注入
1.在BookDaoImpl类中声明对应的简单数据类型的属性
2.为这些属性提供对应的setter方法
3.在applicationContext.xml中配置
在BookDaoImpl类中声明对应的简单数据类型的属性,并提供对应的setter方法
public class BookDaoImpl implements BookDao {
private String databaseName;
private int connectionNum;
public void setConnectionNum(int connectionNum) {
this.connectionNum = connectionNum;
}
public void setDatabaseName(String databaseName) {
this.databaseName = databaseName;
}
public void save() {
System.out.println("book dao save..."+databaseName+","+connectionNum);
}
}
在applicationContext.xml配置文件中使用property标签注入
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<property name="databaseName" value="mysql"/>
<property name="connectionNum" value="10"/>
</bean>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"></property>
<property name="userDao" ref="userDao"></property>
</bean>
value:后面跟的是简单数据类型,对于参数类型,Spring在注入的时候会自动转换,但是不能写成英文,spring在将英文转换成int类型的时候就会报错。
引用数据类型使用的是 <property name="" value=""/>
简单数据类型使用的是 <property name="" ref=""/>
2.构造器注入
项目中添加BookDao、BookDaoImpl、UserDao、UserDaoImpl、BookService和 BookServiceImpl类
public interface BookDao {
public void save();
}
public class BookDaoImpl implements BookDao {
private String databaseName;
private int connectionNum;
public void save() {
System.out.println("book dao save...");
}
}
public interface UserDao {
public void save();
}
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("user dao save ...");
}
}
public interface BookService {
public void save();
}
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
xml文件
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
运行文件
public class AppForLifeCycle {
public static void main( String[] args ) {
ApplicationContext ctx = new
ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookService = (BookService) ctx.getBean("bookService");
bookService.save();
}
}
2.1构造器引用类型注入
1.添加带有bookDao参数的构造方法
2.在applicationContext.xml中配置
在BookServiceImpl类中添加带有bookDao参数的构造方法
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
public BookServiceImpl(BookDao bookDao) {
this.bookDao = bookDao;
}
}
在applicationContext.xml中配置
<constructor-arg name="" ref=""/>
name属性对应的值为构造函数中方法形参的参数名,必须要保持一致。
ref属性指向的是spring的IOC容器中其他bean对象。
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<constructor-arg name="bookDao" ref="bookDao"/>
</bean>
2.2构造器多个引用类型注入
在BookServiceImpl声明多个类并提供多个参数的构造函数
public class BookServiceImpl implements BookService {
private BookDao bookDao;
private UserDao userDao;
public BookServiceImpl(BookDao bookDao,UserDao userDao) {
this.bookDao = bookDao;
this.userDao = userDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
userDao.save();
}
}
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<constructor-arg name="bookDao" ref="bookDao"/>
<constructor-arg name="userDao" ref="userDao"/>
</bean>
2.3构造器多个基本类型注入
1.提供一个包含这两个参数的构造方法
2.在applicationContext.xml中进行注入配置
修改BookDaoImpl类,添加构造方法
public class BookDaoImpl implements BookDao {
private String databaseName;
private int connectionNum;
public BookDaoImpl(String databaseName, int connectionNum) {
this.databaseName = databaseName;
this.connectionNum = connectionNum;
}
public void save() {
System.out.println("book dao save..."+databaseName+","+connectionNum);
}
}
在applicationContext.xml中进行注入配置
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<constructor-arg name="databaseName" value="mysql"/>
<constructor-arg name="connectionNum" value="100"/>
</bean>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<constructor-arg name="bookDao" ref="bookDao"/>
<constructor-arg name="userDao" ref="userDao"/>
</bean>
当构造函数中方法的参数名发生变化后,配置文件中的name属性也需要跟着变
方式一:删除name属性,添加type属性,按照类型注入
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<constructor-arg type="int" value="10"/>
<constructor-arg type="java.lang.String" value="mysql"/>
</bean>
这种方式可以解决构造函数形参名发生变化带来的耦合问题 但是如果构造方法参数中有类型相同的参数,这种方式就不友好了
方式二:删除type属性,添加index属性,按照索引下标注入,下标从0开始
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<constructor-arg index="1" value="100"/>
<constructor-arg index="0" value="mysql"/>
</bean>
这种方式可以解决参数类型重复问题 但是如果构造方法参数顺序发生变化后,这种方式又带来了耦合问题