Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架。
轻量--
控制反转---
面向切面---
容器----
面向接口编程
什么是接口
1.接口定义了行文的协议,这些行为在继承接口的类中实现
2.接口定义了很多方法,但是没有实现他们。类履行接口协议并实现所有定义在接口中的方法
3.接口是一种只有声明没有实现的特殊类
接口的优点:
1.Client不必知道其所使用对象的具体所属类
2.一个对象可以很容易地被(实现了相同接口的)的另一个对象所替换
3.对象间的连接不必硬绑定(hardwrite)到另一个具体类的对象上,因此增加了灵活性
4.松散藕合
5.增加了重用的可能性
1.设计用户持久化类的接口UserDao,代码如下:
public interface UserDao{
public void save(User user);
public User load(String name);
}
2.具体的持久化类必须要继承UserDao接口,并实现它的所有方法。我们首先还是实现内存持久化的用户类:
public class MemoryUserDao implements UserDao{
private static Map users=new HaspMap();
static{
User user=new User("Moxie","pass");
users.put(user.getName(),user);
}
public void save(User user){
users.put(user.getId(),user);
}
public User load(String name){
return (User)users.get(name);
}
}
MemoryUserDao的实现代码和上面的MemoyUserPersist基本相同,唯一区别是MemoryUserDao类继承了UserDao接口,它的save()和load()方法是实现接口的方法。
这时,客户端UserRegister的代码又该如何实现呢?
UserDao userDao=new MemoryDao();
userDao.save();
如果我们再切换到文本的持久化实现TextUserDao,客户端代码仍然需要手工修改。虽然我们已经使用了面向对象的多台技术,对象userDao方法的执行都是针对接口的调用,但userDao对象的创建却依赖于具体的实现类,比如上面MemoryUserDao.这样我们并没有完全实现前面所说的“Client不必知道其适用对象的集体所属类”
如何解决客户端对象依赖具体是i胺类的问题呢?
工厂(Factory)模式出场了!
(spring实现用户调用某个类的时候真正的不用再实例化某个具体的类,而是仅仅调用它的实现接口就可以完成所要达到的目的!)
重构第二步-工厂(Factory)模式
我们使用一个工厂类来实现userDao对象的创建,这样客户端只要知道这一个工厂类就可以了,不用依赖任何具体的UserDao实现。创建userDao对象的工厂类UserDaoFactory代码如下:
public class UserDaoFactory{
public static UserDao createUserDao(){
return new MemoryUserDao();
}
}
客户端UserRegister代码片段如下:
UserDao userDao=UserDaoFactory.CreateUserDao();
userDao.save();
现在如果再要更换持久化方式,比如使用文本文件持久化用户信息。就算有再多的客户代码调用了用户持久化对象我们都不用担心了。因为客户端和用户持久化对象的具体实现完全解耦。我们唯一要修改的只是一个UserDaoFactory类。
重构第三步-工厂(Factory)模式的改进
但到这里,假如将内存持久化改为文本文件持久化仍然有着硬编码的存在----UserDaoFactory类的修改。代码的修改就意味着重新编译,打包,部署甚至引入新的Bug.
那怎样才能够达到完美的解决方案?至少要消除更换持久化方式时带来的硬编码。具体实现类的可配置不正是我们需要的吗?我们在一个属性文件中配置UserDao的实现类,例如:在 属性文件中可以这样配置:userDao=com.test.MemoryUserDao.UserDao的工厂类将从这个属性文件中取得UserDao实现类的全名,再通过Class.forName(className).newInstance()语句来自动创建一个UserDao接口的具体实例。UserDaoFactory代码如下:
public class UserDaoFactory {
public static UserDao createUserDao(){
String className="";
//从属性文件中取得这个UserDao的实现类全名
UserDao userDao=null;
try{
userDao=(UserDao)Class.forName(className).newInstance();
}catch(Exxception e) {
e.printStackTrace();
}
return userDao;
}
通过对工厂模式的优化,我们的方案已近乎完美。如果现在要更换持久化方式,不需要再做任何的手工编码,只要修改配置文件中的userDao实现类名,将它设置为你需要更换的持久化类名即可。
重构第四步-IOC容器
使用IOC容器,用户注册类UserRegister不用主动创建UserDao实现类的实例。由IOC容器主动穿件UserDao实现类的实例,并注入到用户注册类中。我们下面将使用Spring提供的Ioc容器来管理我们的用户注册类
用户注册类UserRegister的部分实现代码如下:
public class UserRegister{
private UserDao userDao=null; //由容器注入的实例对象
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
//UserRegister的业务方法
在其他的UserRegister方法中就可以直接使用userDao对象了,它的实例由Spring容器主动为他创建。但是,如何组装一个UserDao的实现类到UserRegister中呢?Spring提供了配置文件来组装我们的组件。Spring的配置文件applicationContetxt.xml代码片段如下:
<bean id="userRegister" class="com.dev.spring.simple.UserRegister">
<property name="userDao"><ref local="userDao " /></property>
</bean>
<bean id="userDao" class="com.dev.spring.simple.MemoryUserDao"/>
控制反转(IOC)/依赖注入(DI)
控制反转(IOC-INVERSION OF CONTROL)ioc,就是有容器控制程序之间的依赖关系。而非传统实现中,由程序代码直接操控。控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。
IOC也称为好莱坞原则:即,如果大腕明星想演节目,不用自己去找好莱坞公司,而是由好莱坞公司主动去找他们。(当然之前这些明星必须要在好莱坞登记过)
BeanFactory
BeanFactory是Spring的心脏。他就是Spring IOC容器的真面目。Spring使用BeanFactory来实例化,配置和管理Bean。但是,在大多数情况下我们并不直接使用BeanFactory,而是使用ApplicationContext..他也是BeanFactory的一个实现,但是他添加了一系列“框架”的特征,比如:国际化支持,资源访问,事件传播等。ApplicationContext我们将后序介绍。
轻量--
控制反转---
面向切面---
容器----
面向接口编程
什么是接口
1.接口定义了行文的协议,这些行为在继承接口的类中实现
2.接口定义了很多方法,但是没有实现他们。类履行接口协议并实现所有定义在接口中的方法
3.接口是一种只有声明没有实现的特殊类
接口的优点:
1.Client不必知道其所使用对象的具体所属类
2.一个对象可以很容易地被(实现了相同接口的)的另一个对象所替换
3.对象间的连接不必硬绑定(hardwrite)到另一个具体类的对象上,因此增加了灵活性
4.松散藕合
5.增加了重用的可能性
代码重构:
1.设计用户持久化类的接口UserDao,代码如下:
public interface UserDao{
public void save(User user);
public User load(String name);
}
2.具体的持久化类必须要继承UserDao接口,并实现它的所有方法。我们首先还是实现内存持久化的用户类:
public class MemoryUserDao implements UserDao{
private static Map users=new HaspMap();
static{
User user=new User("Moxie","pass");
users.put(user.getName(),user);
}
public void save(User user){
users.put(user.getId(),user);
}
public User load(String name){
return (User)users.get(name);
}
}
MemoryUserDao的实现代码和上面的MemoyUserPersist基本相同,唯一区别是MemoryUserDao类继承了UserDao接口,它的save()和load()方法是实现接口的方法。
这时,客户端UserRegister的代码又该如何实现呢?
UserDao userDao=new MemoryDao();
userDao.save();
如果我们再切换到文本的持久化实现TextUserDao,客户端代码仍然需要手工修改。虽然我们已经使用了面向对象的多台技术,对象userDao方法的执行都是针对接口的调用,但userDao对象的创建却依赖于具体的实现类,比如上面MemoryUserDao.这样我们并没有完全实现前面所说的“Client不必知道其适用对象的集体所属类”
如何解决客户端对象依赖具体是i胺类的问题呢?
工厂(Factory)模式出场了!
(spring实现用户调用某个类的时候真正的不用再实例化某个具体的类,而是仅仅调用它的实现接口就可以完成所要达到的目的!)
重构第二步-工厂(Factory)模式
我们使用一个工厂类来实现userDao对象的创建,这样客户端只要知道这一个工厂类就可以了,不用依赖任何具体的UserDao实现。创建userDao对象的工厂类UserDaoFactory代码如下:
public class UserDaoFactory{
public static UserDao createUserDao(){
return new MemoryUserDao();
}
}
客户端UserRegister代码片段如下:
UserDao userDao=UserDaoFactory.CreateUserDao();
userDao.save();
现在如果再要更换持久化方式,比如使用文本文件持久化用户信息。就算有再多的客户代码调用了用户持久化对象我们都不用担心了。因为客户端和用户持久化对象的具体实现完全解耦。我们唯一要修改的只是一个UserDaoFactory类。
重构第三步-工厂(Factory)模式的改进
但到这里,假如将内存持久化改为文本文件持久化仍然有着硬编码的存在----UserDaoFactory类的修改。代码的修改就意味着重新编译,打包,部署甚至引入新的Bug.
那怎样才能够达到完美的解决方案?至少要消除更换持久化方式时带来的硬编码。具体实现类的可配置不正是我们需要的吗?我们在一个属性文件中配置UserDao的实现类,例如:在 属性文件中可以这样配置:userDao=com.test.MemoryUserDao.UserDao的工厂类将从这个属性文件中取得UserDao实现类的全名,再通过Class.forName(className).newInstance()语句来自动创建一个UserDao接口的具体实例。UserDaoFactory代码如下:
public class UserDaoFactory {
public static UserDao createUserDao(){
String className="";
//从属性文件中取得这个UserDao的实现类全名
UserDao userDao=null;
try{
userDao=(UserDao)Class.forName(className).newInstance();
}catch(Exxception e) {
e.printStackTrace();
}
return userDao;
}
通过对工厂模式的优化,我们的方案已近乎完美。如果现在要更换持久化方式,不需要再做任何的手工编码,只要修改配置文件中的userDao实现类名,将它设置为你需要更换的持久化类名即可。
重构第四步-IOC容器
使用IOC容器,用户注册类UserRegister不用主动创建UserDao实现类的实例。由IOC容器主动穿件UserDao实现类的实例,并注入到用户注册类中。我们下面将使用Spring提供的Ioc容器来管理我们的用户注册类
用户注册类UserRegister的部分实现代码如下:
public class UserRegister{
private UserDao userDao=null; //由容器注入的实例对象
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
//UserRegister的业务方法
在其他的UserRegister方法中就可以直接使用userDao对象了,它的实例由Spring容器主动为他创建。但是,如何组装一个UserDao的实现类到UserRegister中呢?Spring提供了配置文件来组装我们的组件。Spring的配置文件applicationContetxt.xml代码片段如下:
<bean id="userRegister" class="com.dev.spring.simple.UserRegister">
<property name="userDao"><ref local="userDao " /></property>
</bean>
<bean id="userDao" class="com.dev.spring.simple.MemoryUserDao"/>
控制反转(IOC)/依赖注入(DI)
控制反转(IOC-INVERSION OF CONTROL)ioc,就是有容器控制程序之间的依赖关系。而非传统实现中,由程序代码直接操控。控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。
IOC也称为好莱坞原则:即,如果大腕明星想演节目,不用自己去找好莱坞公司,而是由好莱坞公司主动去找他们。(当然之前这些明星必须要在好莱坞登记过)
BeanFactory
BeanFactory是Spring的心脏。他就是Spring IOC容器的真面目。Spring使用BeanFactory来实例化,配置和管理Bean。但是,在大多数情况下我们并不直接使用BeanFactory,而是使用ApplicationContext..他也是BeanFactory的一个实现,但是他添加了一系列“框架”的特征,比如:国际化支持,资源访问,事件传播等。ApplicationContext我们将后序介绍。