Spring--开源的控制反转(Inversion of Control,IoC)和面向切面(AOP)的
容器框架.
一.IOC 控制反转
public class PersonServiceBean
{
private PersonDao personDao = new PersonDaoBean();
public void save(Person person)
{
personDao.save(person);
}
}
PersonDaoBean 本来是在应用内部创建及维护的。而所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建和维护是由外部容器负责的。这样控制权就转移到了外部容器,控制权的转移就是所谓的反转。
二.依赖注入(Dependency Injection)
当我们把依赖对象交给外部容器负责创建,那么PersonServiceBean类就可以改成:
public class PersonServiceBean
{
private PersonDao personDao;
//通过构造器参数,让容器把创建好的依赖对象注入进PersonServiceBean,当然也可以通过setter 的方法进行注入
public PersonServiceBean(PersonDao person)
{
this.personDao = person;
}
public void save(Person person)
{
personDao.save(person);
}
}
所谓依赖注入就是指:在运行期间,由外部容器动态的将依赖对象注入到组件中。
三.Spring 的好处:
1.降低组件之间的耦合度,实现软件各层之间的解耦。
Controller --> Service --> Dao
2.可以使用容器提供的众多服务,如:事务管理服务,消息服务等等。当我们使用容器管理服务时,开发人员就不需要手工控制事务,也不需要处理复杂的事务传播了。
3.容器提供单例模式支持,开发人员不再需要自己编写实现代码。
4.容器提供AOP技术,利用它很容易实现如权限拦截,运行期监控等功能。
5.容器提供众多辅助类,使用这些类可以提高开发速度,如:JdbcTemplate,HibernateTemplate.
6.Spring 对于主流的应用框架提供了集成支持,如:Hibernate,JPA,Struts等。
四.使用Spring 管理事务
1.Hibernate 事务操作:
public void save()
{
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Info info = new Info("XXX");
info.setContent("内容");
session.save(info);
session.getTransaction().commit();
}
2.JDBC 事务操作:
Connection conn = null;
try{
.......
Statament stmt = conn.createStatement();
stmt.executeUpdate("update person where name='xx'");
conn.commit();
.......
}catch(Exception e)
{
......
}
=====================================
2.如果不使用Spring完成下面两个需求代码如下:
第一种:要求Bean1和Bean2 在同一个事务中执行。
修改两个Bean 代码如下:
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 (?)");
}
}
第二种:要求不管Bean1的update()是否成功,都要记录操作日志。
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 (?)");
}
}
3.如果使用Spring,我们只需要通过申明式的事务属性配置就可以轻松地实现这两种业务需求。
第一种:要求Bean1和Bean2 在同一个事务中执行。
@Transactional(propagation=propagation.Required)
public void payment()
{
Bean1.update(); //更新金额
Bean2.save(); //记录日志
}
public class Bean1
{
@Transational(propagation = Propagation.Required)
public void update()
{
executeUpdate("update account set amount=? where id=?");
}
}
public class Bean2
{
@Transational(propagation = Propagation.Required)
public void save()
{
executeUpdate("insert into Log(content) values(?)");
}
}
第二种:要求不管Bean1.update()的事务是否成功,都需要记录日志。
@Transactional(propagation=propagation.Required)
public void payment()
{
Bean1.update(); //更新金额
Bean2.save(); //记录日志
}
public class Bean1
{
@Transational(propagation = Propagation.Required)
public void update()
{
executeUpdate("update account set amount=? where id=?");
}
}
public class Bean2
{
@Transational(propagation = Propagation.RequiresNew)
public void save()
{
executeUpdate("insert into Log(content) values(?)");
}
}