spring是一个开源的控制反转(Inversion of Control,IOC)和面向切面(AOP)的容器框架,它的主要目的是简化企业开发。
spring框架的优点:
- 轻量级 的容器框架,没有侵入性
- IOC更加容易组合对象之间的关系,通过面向接口进行编程,可以低耦合开发。
- 易于本地测试(Junit单元测试,不用部署服务器)
- AOP可以更加容易的进行功能扩展,遵循OCP开发原则。
- Spring默认对象的创建为单例的,我们不需要再使用单例的设计模式来开发单体类。
- Spring的集成很强大,另外可以对其他框架的配置进行一元化管理
- Spring的声明式事务的方便使用
Spring主要内容
从下向上看Spring的主要内容
(1)Test:Spring支持Junit单元测试
(2)核心容器(Core Container):
Beans:Bean工厂,创建对象
Core:核心工具类
Context:运行时spring容器,上下文
SpEL:Spring的表达式语言
(3)AOP
AOP:基于代理的AOP支持
Aspects:基于AspectJ的AOP支持
(4)消息(Message)
Message:对消息架构和协议的支持
(5)Web
Web:提供基础的Web集成的功能,在Web项目中提供Spring的容器
Webmvc:提供基于Servlet的Spring MVC
WebSocket:提供WebSocket功能
Webmvc-Portlet:提供Portlet环境支持
(6)数据访问/集成(Data Access/Integration)
JDBC:提供以JDBC访问数据库的支持
Transactions:提供编程式和声明式的事务支持
ORM:提供对对象/关系映射技术的支持
OXM:提供对对象/xml映射技术的支持
JMS:提供对JMS的支持
下面我们通过示例来简单理解下IOC(控制反转)思想
1、定义DAO接口UserDao
public interface UserDao {
public void getUser();
}
2、定义DAO接口实现类UserDaoImpl和UserDaoOracleImpl
UserDaoImpl:
public class UserDaoImpl implements UserDao{
@Override
public void getUser() {
System.out.println("获取用户数据");
}
}
UserDaoOracleImpl:
public class UserDaoOracleImpl implements UserDao{
@Override
public void getUser() {
System.out.println("Oracle获取用户数据");
}
}
3、定义Service层接口UserService,实现具体业务
public interface UserService {
public void getUser();
}
4、定义Service接口的实现类UserServiceImpl,Service层的业务实现,具体要调用到已定义的Dao层接口
我们传统的Java SE设计思想,代码是这样组织的:我们直接在对象内部(应用程序本身)通过new进行创建对象,是程序主动去创建依赖对象
public class UserServiceImpl implements UserService{
private UserDao userDao=new UserDaoImpl();
@Override
public void getUser() {
userDao.getUser();
}
}
在我们的测试类Test中
public class Test {
public static void main(String[] args) {
UserServiceImpl userService=new UserServiceImpl();
userService.getUser();
}
}
如果需要替换DAO接口的具体实现类的时候,我们需要将UserServiceImpl中的
private UserDao userDao=new UserDaoImpl();
修改为:
private UserDao userDao=new UserDaoOracleImpl();
控制反转(IOC)的设计思想,我们不需要应用程序本身来创建对象,而是将创建对象的任务交付给IOC容器:此时,我们在UserServiceImpl可以这样编写代码
public class UserServiceImpl implements UserService{
// private UserDao userDao=new UserDaoOracleImpl();
private UserDao userDao=null;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
添加一个set方法,当调用端需要创建对象的时候,创建具体实体类的对象,此时我们在Test类中就可以这样组织代码:
public class Test {
public static void main(String[] args) {
UserServiceImpl userService=new UserServiceImpl();
userService.setUserDao(new UserDaoImpl());
userService.getUser();
System.out.println("--------");
userService.setUserDao(new UserDaoOracleImpl());
userService.getUser();
}
}
Test测试类运行结果:
获取用户数据
--------
Oracle获取用户数据
示例总结:
1)对象由原来程序本身创建,变为了程序接收对象
2)程序员主要精力集中与业务的实现
3)实现了service和dao的解耦工作,没有直接依赖关系,层与层之间实现了分离(service和Dao没有关系,完全分离)
4)如果dao的实现发生变化,应用程序本身不用改变(更改Spring的配置文件)