目录
传统方式建立一个对象:
1.最原始方法:
2..面向接口方法:
3.工厂模式
4.工厂+反射+配置文件 实现程序解耦
将实现类交给Spring管理
1.编写配置文件applicationContext.xml
2.编写测试类
SpringIOC与DI
1.springIOC与DI的关系
2.如何理解DI
3.如何使用DI
传统方式建立一个对象:
1.最原始方法:
UserDAO userDao = new UserDAO();
2..面向接口方法:
用户管理的DAO层接口:
package com.rosinante.spring.iocdemo;
/*
* 用户管理DAO接口
*/
public interface UserDAO {
public void save();
}
以及他的实现类 :
package com.rosinante.spring.iocdemo;
/*
* DAO层实现类
*/
public class UserDAOImpl implements UserDAO {
public void save(){
System.out.println("UserDAO......");
}
}
写一个SpringIocDemo类来调用这个接口:
package com.rosinante.spring.iocdemo;
import org.junit.Test;
public class SpringIocDemo {
@Test
/*
* 传统方式调用
*/
public void demo(){
UserDAO userDAO = new UserDAOImpl();
userDAO.save();
}
}
面向接口的好处是实现了程序的多态,易拓展,但接口与实现类有耦合,例如将此例改为Hibernate实现,则需要创建一个Hibernate的实现类UserDAOHibernateImpl这意味着我们要切换底层实现类需要修改大量源代码。好的程序设计应满足OCP原则,在尽量不修改程序源码的基础上对程序进行拓展。
3.工厂模式
原先的接口方式接口与实现类直接产生关系,通过工厂避免直接产生关系。
例如创建一个BeanFactory的工厂类:
class BeanFactory{
public static UserDAO getUserDAO(){
return new UserDAOImpl();
}
public static CustomerDAO getCustomerDAO(){
return new CustomerDAOImpl();
}
......
}
把所有类的创建都交给工厂来实现,接口和实现类之间没有耦合,但是接口和工厂有耦合,要切换实现类的时候,还是要修改工厂类的源码,但好处是之前面向接口的方式需要修改很多类,工厂模式只需要修改工厂类。比如改为Hibernate方式实现时,只需要修改工厂类这一个类:
class BeanFactory{
public static UserDAO getUserDAO(){
return new UserDAOHibernateImpl();
}
public static CustomerDAO getCustomerDAO(){
return new CustomerDAOImpl();
}
......
}
4.工厂+反射+配置文件 实现程序解耦
例如有配置文件xml如下:
<bean id = "UserDAO" class = "xxx.UserDAOImpl"></bean>
工厂类:
class BeanFactory{
public static Object getBean(String id){
//解析XML 找到对应的class
//反射
Class class = Class.forName();
return class.newInstance();
}
}
实际上SpringIoc的底层实现就是通过这样的方式。
将实现类交给Spring管理
1.编写配置文件applicationContext.xml
applicationContext是spring配置文件的默认名称,当然也可以使用其他的命名。
<?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">
<!-- spring入门配置 -->
<bean id="userDAO" class="com.rosinante.spring.iocdemo.UserDAOImpl"></bean>
</beans>
如上我们将UserDAOImpl交给spring来管理。
2.编写测试类
package com.rosinante.spring.iocdemo;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringIocDemo {
private Object bean;
@Test
/*
* 传统方式调用
*/
public void demo(){
UserDAO userDAO = new UserDAOImpl();
userDAO.save();
}
@Test
/**
* Spring方式的调用
*/
public void demo2(){
//创建Spring的工厂
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//传入id:UserDAO 返回UserDAO的实例
UserDAO userDAO = (UserDAO)applicationContext.getBean("userDAO");
userDAO.save();
}
}
之后如果需求改变,只需要将配置文件更改一下即可。
SpringIOC与DI
1.springIOC与DI的关系
SpringIOC意为控制反转,即将对象的创建反转给了Spring,DI依赖注入是实现IOC的方式,DI依靠IOC容器。
2.如何理解DI
面向对象中,对象之间有如下关系:
- 依赖
Class A{
......
}
Class B{
public void xxx(A a){ //xxx方法的参数需要类A的对象 类B对A产生了依赖
......
}
}
- 继承
Class A{
......
}
Class B extends A{
......
}
- 聚合
聚合是整体和个体之间的关系,例如球队和球员,英文字母和abc之间的关系
// 母亲
class Mother {
// 母亲可以有自己孩子, 但是不确定什么时候生
private Children myChildren;
}
// 孩子
class Children {
}
DI就是将依赖的值设置进去,例如UserDAOImpl这个实现类中,添加一个属性name:
package com.rosinante.spring.iocdemo;
/*
* DAO层实现类
*/
public class UserDAOImpl implements UserDAO {
private String name; //增加的属性
public void setName(String name) {
this.name = name;
}
public void save(){
System.out.println("UserDAO......"+name);
}
}
那么我们在测试类中无法使用面向接口的方式赋值,必须通过创建一个实现类的对象来给name赋值:
public class SpringIocDemo {
private Object bean;
@Test
/*
* 传统方式调用
*/
public void demo(){
//UserDAO userDAO = new UserDAOImpl();
//接口中没有set发法 只能使用实现类来创建对象
UserDAOImpl userDAO = new UserDAOImpl();
userDAO.setName("二狗");
userDAO.save();
}
......
}
这样做的弊端有:
- 不能使用面向接口的方式编程
- 必须手动设置属性值
- 需要改变程序源代码
3.如何使用DI
在applicationContext.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">
<!-- spring入门配置 -->
<bean id="userDAO" class="com.rosinante.spring.iocdemo.UserDAOImpl">
<!-- 属性注入 -->
<property name="name" value="ergou"></property>
</bean>
</beans>
运行测试类中的demo2方法,控制台成功打印。