Spring 成功的是其提出的理念,而不是技术本身,它所依赖的两个核心概念,一个是控制反转(Inversion of Control, IOC),另一个是面向切面编程(Aspect Oritented Programming,AOP)
IOC:
IOC容器是Spring框架的核心,可以说Spring是一种基于IOC容器的编程框架。 IOC是一种通过描述来产生或者获取对象的技术,这个技术不是Spring甚至Java独有的,对于Java初学者更多的时候所 熟悉的是使用new关键字来创建对象,而是在Spring中则不是,它是通过描述来创建对象。
一个系统可以生成各种对象,并且这些对象都需要进行管理,还值得一提的是,对象之间并不是孤立的,它们之间还有 可能存在依赖的关系。例如,一个班级是由多个老师和学生组成的。那么班级就依赖于多个老师和学生了。 为此Spring还提供了依赖注入(DI)的功能,使得我们能够通过描述来管理各个对象之间的关系。
为了描述上述的班级,学生,老师这3个对象的关系,我们需要一个容器。在Spring中把每一个需要管理的对象称为 Spring Bean (简称 Bean),而Spring 管理这些Bean的容器,被我们称为SpringIOC容器。
IOC容器需要具备两个基本功能:
1> 通过描述管理Bean,包括发布和获取Bean 2> 通过描述完成Bean之间的依赖关系
AOP:
为什么使用AOP AOP为典型的应用实际就是数据库事务的管控。 例如:当我们需要保存一个用户时,可能要连同它的角色信息一并保存在数据库中
这里用户信息和角色信息,我们都可以使用面向对象编程OOP设计,但是它们在数据库事务中的要求是, 要么一起成功,要么一起失败,这样OOP就无能为力了。数据库事务毫无疑问是企业级应用关注的核心问题之一, 而使用AOP可以解决这些问题。
AOP还可以减少大量重复的工作。在Spring框架流行之前,我们可以使用JDBC代码实现很多的数据库的操作。 例如插入一个用户信息。
public class UserService{
public int insertUser(){
UserDAO userDAO=new UserDAO();
User user=new User();
user.setUserName("小张");
user.setNote("备注");
Connection conn=null;
int result=0;
try{
//获取事务连接
Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection("jdbc:mysql://localhost:3006/数据库 名","root","123456");
//非自动提交事务
conn.setAutoCommit(false);
result=userDAO.insertUser(conn,user);
//提交事务
conn.commit();
}catch(Exception e){
try{
conn.rollback();
}catch(SQLException e){
e.printStackTrace();
} e.printStackTrace();
}
return result;
}
}
public class UserDAO{
public int insertUser(Connection conn,User user) throws SQLException{
PreparedStatement ps=null;
try{
ps=conn.prepareStatement("insert into t_user(user_name,note) values(?,?)");
ps.setString(1,user.getUserName());
ps.setString(2,user.getNote());
return ps.executeUpdate();
}finnaly{
ps.close();
}
关于数据库的打开和关闭以及事务的提交和回滚都有流程默认给你实现。 换句话说,你都不需要完成它们,你需要完成的任务是编写SQL这一步而已,然后织入流程中。 在Spring开发的代码:
@Autowired private UserDao userDao=null;
@Transactional public int insertUser(User user){
return userDao.insertUser(user); }
AOP也是一种约定编程。这里可以看到仅仅使用了一个注解@Transactional,表明该方法需要事务运行, 没有任何数据库打开和关闭的代码,也没有事务回滚和提交的代码。 却实现了数据库资源的打开和关闭,事务的回滚和提交。那么Spring是怎么做到的呢? Spring帮助你把insertUser方法织入类似上图所示的流程中, 数据库连接的打开和关闭以及事务管理都由它给你默认实现,也就是它可以将大量重复的流程通过约定 的方式抽取出来,然后给予默认的实现。例如,这里的数据库连接的打开和释放、事务的处理可见它可以 帮助我们减少大量的代码,尤其那些麻烦的try…catch…finally
AOP术语
对应的是具体被拦截的对象,因为Spring只能支持方法,所以被拦住的对象往往就是指特定的方法。 例如 HelloServiceImpl的sayHello方法就是一个连接点,AOP将通过动态代理技术把它织入对应的流程中。
有时候,我们的切面不单单应用于单个方法,也可能是多个类的不同方法,这时,可以通过正则式和指示器规则去定 义,从而适配连接点。切点就是提供这样一个功能的概念。
就是按照约定的流程下的方法,分为前置通知(before advice)、后置通知(after advice)、 环绕通知(around advice),事后返回通知(afterReturning advice)和异常通知(afterThrowing advice) 它会根据约定织入流程中,需要弄明白他们在流程中的顺序和运行条件。
即被代理的对象,例如 HelloServiceImpl实例就是一个目标对象,它被代理了。
是指引入新的类和其方法,增强现有的Bean的功能
它是一个通过动态代理技术,为原有服务对象生成代理对象,然后将与切点定义匹配的连接点拦截,并按照约定 将各类通知织入约定流程的过程。
是一个可以配置切点,各类通知和引入的内容,Spring AOP将通过它的信息来增强Bean的功能或者将对应的方法织入流 程。