IoC
Inversion of Control 使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转
Spring实现了IoC的思想,Spring提供了一个容器,称为IoC容器,用来充当IoC思想中的外部
Ioc容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在Ioc容器中统称为Bean
DI
Dependency Injection 依赖注入,在容器建立bean于bean之间的依赖关系的过程
IoC的使用
首先,还是需要我们导入一个Maven坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
之后,在resources文件夹下,新建一个Spring的XML配置文件 之后再配置文件中,配置bean id表示给bean取名字 class定义bean的类型
<bean id="bookDao" class="com.dao.impl.BookDaoImpl"></bean>
获取IoC容器
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
获取bean
BookDao bookDao = (BookDao) context.getBean("bookDao");
DI的使用
在类中定义一个set方法
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;
}
}
配置二者的关系 name中要填的是set方法后的首字符改小写后的结果 ref中填的是bookDao的bean的名字
<bean id="bookService" class="com.service.Impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"></property>
</bean>
还是获取IoC容器和bean
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookService = (BookService) context.getBean("bookService");
bean标签的说明
bean是默认为单例 但是可以通过修改其scope属性来改变其是否为单例
修改为非单例
<bean id="bookDao" class="com.dao.impl.BookDaoImpl" scope="prototype"></bean>
还可以给bean设置名字 name属性中的所有都可以为改bean的名字
<bean id="bookDao" name="asdas adasdasasd asdasad" class="com.dao.impl.BookDaoImpl" ></bean>
Bean的实例化方法
第一种
构造方法,提供可访问的构造器,它的底层是基于反射的原理,因此无论构造器私有与否,其都能获取 想之前示例中的就是这种方法,不过一般无参构造器器默认不写。
第二种
静态工厂
下面是一个标准的工厂模式
public interface UserDao {
public void save();
}
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("userdao save");
}
}
public class UserDaoFactory {
public static UserDao getUserDao(){
return new UserDaoImpl();
}
}
对于这种静态的工厂,我们的bean对象配置,也要变化
<bean id="UserDao" class="factory.UserDaoFactory" factory-method="getUserDao"></bean>
第三种
实例工厂
一个实例工厂
public class OrderDaoImpl implements OrderDao {
@Override
public void save() {
System.out.println("OrderDao save");
}
}
public interface OrderDao {
public void save();
}
public class OrderDaoFactory {
public OrderDao getOrderDao(){
return new OrderDaoImpl();
}
}
对于这种我们就需要自己创建一个工厂的bean对象
<bean id="OrderDaoFactory" class="factory.OrderDaoFactory"></bean>
<bean id="OrderDao" factory-method="getOrderDao" factory-bean="OrderDaoFactory"></bean>
那么有没有一种不需要建立额外的bean对象的方法呢
显然是有的,我们可以实现一下FactoryBean接口,这个接口是一个泛型接口,因此我们可以在里面确定一个类
public class OrderDaoFactoryBean implements FactoryBean<OrderDao> {
@Override
public OrderDao getObject() throws Exception {
return new OrderDaoImpl();
}
@Override
public Class<?> getObjectType() {
return OrderDao.class;
}
}
这时候配置bean对象就非常的简单了
<bean id="OrderDao" class="factory.OrderDaoFactoryBean"></bean>
依赖注入
setter注入
就是在要创建的bean类中加入set方法
不仅仅可以为类,也可以是基本的数据类型
public class BookServiceImpl implements BookService {
private BookDao bookDao;
private int number;
public void save(){
System.out.println("book service save");
System.out.println(number);
bookDao.save();
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
bean配置
<bean id="bookService" class="com.service.Impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"></property>
<property name="number" value="10"></property>
</bean>
构造器注入
其实就是用一个构造器取代set方法
public class BookServiceImpl implements BookService {
private BookDao bookDao;
private int number;
public BookServiceImpl(BookDao bookDao, int number) {
this.bookDao = bookDao;
this.number = number;
}
public BookServiceImpl() {
}
public void save(){
System.out.println("book service save");
System.out.println(number);
bookDao.save();
}
}
而这里的bean的配置也要做相应的改变
<bean id="bookService" class="com.service.Impl.BookServiceImpl">
<constructor-arg name="bookDao" ref="bookDao"></constructor-arg>
<constructor-arg name="number" value="100"></constructor-arg>
</bean>
不过这种方法的代码耦合度较高,应为name后面的填的和构造器中的形参相关,因此我们可以选择不用name,改用参数的位置下标,index
<bean id="bookService" class="com.service.Impl.BookServiceImpl">
<constructor-arg index="0" ref="bookDao"></constructor-arg>
<constructor-arg index="1" value="100"></constructor-arg>
</bean>
Spring 配置第三方资源
以Druid为例
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/logindemo"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
|