文章40 | 阅读 19288 | 点赞0
阿昀以一个初学者的身份学习Spring框架,并按照一个小白的思路详细总结学习过程中的知识点,整理成一个系列,供后来人借鉴。
Spring是一个开源的控制反转(Inversion of Control,IoC)和面向切面(AOP)的容器框架,它的主要目得是简化企业开发。
大概以前,业务逻辑层的代码很有可能这样写:
public class PersonServiceBean {
private PersonDao personDao = new PersonDaoBean();
public void save(Person person){
personDao.save(person);
}
}
从上可看出PersonDaoBean是在应用内部创建及维护的。所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。
当我们把依赖对象交给外部容器负责创建,那么PersonServiceBean类可以改成如下:
public class PersonServiceBean {
private PersonDao personDao ;
// 通过构造器参数,让容器把创建好的依赖对象注入进PersonServiceBean,当然也可以使用setter方法进行注入。
public PersonServiceBean(PersonDao personDao){
this.personDao=personDao;
}
public void save(Person person){
personDao.save(person);
}
}
所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。
至少在我看来,在项目中引入Spring立即可以带来下面的好处:
上面我们就已详细列出了使用Spring框架带来的好处,我们仅就第二点进行详细说明之。
当使用Spring框架时,我们可以使用容器提供的众多服务。
试想若要是不使用Spring框架,那么使用Hibernate框架进行事务操作就应是:
public void save(){
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Info info = new Info("Spring框架");
info.setContent("阿昀手把手教你学习Spring框架");
session.save(info);
session.getTransaction().commit();
}
既不使用Spring框架,也不使用Hibernate框架,直接使用最原始的JDBC技术进行事务操作,代码就应是:
Connection conn = null;
try {
......
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
stmt.executeUpdate("update person where name='叶天'");
conn.commit();
......
} catch (Exception e) {
conn.rollback();
} finally {
conn.close();
}
而如果使用Spring框架,那我们就不再需要手工控制事务了。另外,如果使用Spring框架,我们也不需要处理复杂的事务传播行为了。我们举例子来说明之。
例如,有代码:
public void payment(){
Bean1.update(); // 更新金额
Bean2.save(); // 记录操作日志
}
public class Bean1 {
public void update(){ // 注意:下面省略了一些代码
Connection conn = null;
conn.setAutoCommit(false);
Statement.executeUpdate("update account set amount=? where id=?");
}
}
public class Bean2 {
public void save(){ // 注意:下面省略了一些代码
Connection conn = null;
conn.setAutoCommit(false);
Statement.executeUpdate("insert into Log (content) values (?)");
}
}
如果我们不使用Spring框架,针对下面这两种业务需求,我们该如何做呢?
若要是不使用Spring框架,针对第1种可能的业务需求,我们的解决办法用代码来表示就是:
public void payment(){
Connection conn = null;
conn.setAutoCommit(false);
Bean1.update(conn); // 更新金额
Bean2.save(conn); // 记录操作日志
// ...提交或回滚事务
}
public class Bean1 {
public void update(Connection conn){ // 注意:下面省略了一些代码
Statement.executeUpdate("update account set amount=? where id=?");
}
}
public class Bean2 {
public void save(Connection conn){ // 注意:下面省略了一些代码
Statement.executeUpdate("insert into Log (content) values (?)");
}
}
针对第2种可能的业务需求,我们不需要修改代码就可完成,因为Bean1.update()开启了一个事务,Bean2.save()同样也开启了一个事务,Bean1.update()开启的事务的回滚不会影响到Bean2.save()开启的事务。
倘若使用Spring框架,我们只需要通过声明式的事务属性配置就可以轻松地实现这两种业务需求。
@Transactional(propagation=Propagation.Required)
public void payment(){
Bean1.update(); // 更新金额
Bean2.save(); // 记录日志
}
public class Bean1 {
@Transactional(propagation=Propagation.Required)
public void update(){
executeUpdate("update account set amount=? where id=?");
}
}
public class Bean2 {
@Transactional(propagation=Propagation.Required)
public void save(){
executeUpdate("insert into Log (content) values (?)");
}
}
@Transactional(propagation=Propagation.Required)
public void payment(){
Bean1.update(); // 更新金额
Bean2.save(); // 记录日志
}
public class Bean1 {
@Transactional(propagation=Propagation.Required)
public void update(){
executeUpdate("update account set amount=? where id=?");
}
}
public class Bean2 {
@Transactional(propagation=Propagation.RequiresNew)
public void save(){
executeUpdate("insert into Log (content) values (?)");
}
}
经常会有人问到Spring是属于轻量级框架,还是属于重量级框架呢?其实划分一个应用是否属于轻量级还是重量级,主要看它使用了多少服务。使用的服务越多,容器要为普通java对象做的工作就越多,必然会影响到应用的发布时间或者是运行性能。
对于Spring容器来说,它提供了很多服务,但这些服务并不是默认为应用打开的,应用需要某种服务,还需要指明使用该服务,如果应用使用的服务很少,如:只使用了Spring核心服务,那么我们可以认为此时应用属于轻量级的,如果应用使用了Spring提供的大部分服务,这时应用就属于重量级的。目前EJB容器就因为它默认为应用提供了EJB规范中所有的功能,所以它属于重量级。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://liayun.blog.csdn.net/article/details/52830571
内容来源于网络,如有侵权,请联系作者删除!