Spring AOP主要就是经过动态代理来实现,而Ioc是经过反射来实现,将建立对象和对象之间的依赖管理交给IoC容器来作,完成对象之间的解耦。java
举个反射的例子,以下:redis
public class Car { private String brand; private String color; private int maxSpeed; public Car() { System.out.println("init car!!"); } public Car(String brand, String color, int maxSpeed) { this.brand = brand; this.color = color; this.maxSpeed = maxSpeed; } public void introduce() { System.out.println("brand:" + brand + ";color:" + color + ";maxSpeed:" + maxSpeed); } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public int getMaxSpeed() { return maxSpeed; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } }
public class ReflectTest { public static Car initByDefaultConst() throws Throwable { // loadClass()方法必须使用全额限定名 ClassLoader loader = Thread.currentThread().getContextClassLoader(); // 每个类在JVM中都拥有一个对应的java.lang.Class对象,用来描述类结构信息 // Class clazz = loader.loadClass("reflect.Car"); Class clazz = Class.forName("reflect.Car"); Constructor cons = clazz.getDeclaredConstructor((Class[]) null); Car car = (Car) cons.newInstance(); Method setBrand = clazz.getMethod("setBrand", String.class); setBrand.invoke(car, "红旗CA72"); Method setColor = clazz.getMethod("setColor", String.class); setColor.invoke(car, "黑色"); Method setMaxSpeed = clazz.getMethod("setMaxSpeed", int.class); setMaxSpeed.invoke(car, 200); return car; } public static Car initByParamConst() throws Throwable { ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class clazz = loader.loadClass("reflect.Car"); Constructor cons = clazz.getDeclaredConstructor(new Class[] { String.class, String.class, int.class }); Car car = (Car) cons.newInstance(new Object[] { "吉利TOPMIX", "绿色", 120 }); return car; } public static void main(String[] args) throws Throwable { Car car1 = initByDefaultConst(); Car car2 = initByParamConst(); car1.introduce(); car2.introduce(); } }
init car!! brand:红旗CA72;color:黑色;maxSpeed:200 brand:吉利TOPMIX;color:绿色;maxSpeed:120
每个类在JVM中都拥有一个对应的java.lang.Class对象,它提供了类结构信息的描述。数组、枚举、注解甚至void都有对应的Class对象。能够从Class对象中获取构造函数、成员变量、方法等类元素的反射对象,并以编程的方式经过这些反射对目标类对象进行操做。spring
Spring中的事务彻底基于数据库的事务,若是数据库引擎使用MyISAM引擎,那Spring的事务实际上是不起做用的。另外,Spring为开发者提供的与事务相关的特性就是事务的传播行为,以下:数据库
事务传播行为类型apache |
说明编程 |
propagation_required数组 |
若是当前没有事务,就新建一个事务,若是已经存在一个事务中,加入到这个事务中。这是最多见的选择(Spring默认的事务传播行为)app |
propagation_supports数据库设计 |
支持当前事务,若是当前没有事务,就以非事务方式执行函数 |
propagation_mandatory(托管) |
使用当前的事务,若是当前没有事务,就抛出异常 |
propagation_requireds_new |
新建事务,若是当前存在事务,把当前事务挂起 |
propagation_not_supported |
以非事务方式执行操做,若是当前存在事务,就把当前事务挂起 |
propagation_never |
以非事务方式执行,若是当前存在事务,则抛出异常 |
propagation_nested |
若是当前存在事务,则在嵌套事务内执行。若是当前没有事务,则执行与propagation_required相似的操做,也就是新建一个事务。父事务回滚,嵌套的事务也要回滚。
|
Spring经过事务传播行为控制当前的事务如何传播到被嵌套调用的目标服务接口方法中。
Spring能够配置事务的属性,可是隔离级别、读写事务属性、超时时间与回滚设置等都交给了JDBC,真正本身实现的只有事务的传播行为。那么何时发生事务的传播行为呢?
public class ForumService { private UserService userService; @Transactional(propagation = Propagation.REQUIRED) public void addTopic() { // add Topic this.updateTopic(); userService.addCredits(); } @Transactional(propagation = Propagation.REQUIRED) public void updateTopic() { // add Topic } public void setUserService(UserService userService) { this.userService = userService; } }
看一下userService中的addCredits()方法,以下:
public class UserService { @Transactional(propagation = Propagation.REQUIRES_NEW) public void addCredits() { } }
而后测试下:
forumService.addTopic();
开启了Spring4日志的DEBUG模式后,输出以下:
- Returning cached instance of singleton bean 'txManager' - Creating new transaction with name [com.baobaotao.service.ForumService.addTopic]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' - Acquired Connection [org.apache.commons.dbcp.PoolableConnection@1948ea69] for JDBC transaction - Switching JDBC Connection [org.apache.commons.dbcp.PoolableConnection@1948ea69] to manual commit - Suspending current transaction, creating new transaction with name [com.baobaotao.service.UserService.addCredits] - Acquired Connection [org.apache.commons.dbcp.PoolableConnection@773e2eb5] for JDBC transaction - Switching JDBC Connection [org.apache.commons.dbcp.PoolableConnection@773e2eb5] to manual commit - Initiating transaction commit - Committing JDBC transaction on Connection [org.apache.commons.dbcp.PoolableConnection@773e2eb5] - Releasing JDBC Connection [org.apache.commons.dbcp.PoolableConnection@773e2eb5] after transaction - Returning JDBC Connection to DataSource - Resuming suspended transaction after completion of inner transaction - Initiating transaction commit - Committing JDBC transaction on Connection [org.apache.commons.dbcp.PoolableConnection@1948ea69] - Releasing JDBC Connection [org.apache.commons.dbcp.PoolableConnection@1948ea69] after transaction - Returning JDBC Connection to DataSource
清楚的看到调用addCredis()方法时建立了一个新的事务,而在这个方法中调用addCredits()方法时,因为这个方法的事务传播行为为progation_required_new,因此挂起了当前的线程,又建立了一个新的线程。可是对于this.updateTopic()方法调用时,因为这个
方法的事务仍然为propagation_required,因此在当前线程事务中执行便可。
在使用事务中咱们须要作到尽可能避免死锁、尽可能减小阻塞,根据不一样的数据库设计和性能要求进行所须要的隔离级别,才是最恰当的。具体如下方面须要特别注意:
A、 事务操做过程要尽可能小,能拆分的事务要拆分开来
B、 事务操做过程不该该有交互(系统交互,接口调用),由于交互等待的时候,事务并未结束,可能锁定了不少资源
C、 事务操做过程要按同一顺序访问对象。(避免死锁的状况产生)
D、 提升事务中每一个语句的效率,利用索引和其余方法提升每一个语句的效率能够有效地减小整个事务的执行时间。
E、 查询时能够用较低的隔离级别,特别是报表查询的时候,能够选择最低的隔离级别(未提交读)。
参考:http://blog.csdn.net/arvinrong/article/details/7756167
SpringMVC设计思路:将整个处理流程规范化,并把每个处理步骤分派到不一样的组件中进行处理。
这个方案实际上涉及到两个方面:
l 处理流程规范化 —— 将处理流程划分为若干个步骤(任务),并使用一条明确的逻辑主线将全部的步骤串联起来
l 处理流程组件化 —— 将处理流程中的每个步骤(任务)都定义为接口,并为每一个接口赋予不一样的实现模式
处理流程规范化是目的,对于处理过程的步骤划分和流程定义则是手段。于是处理流程规范化的首要内容就是考虑一个通用的Servlet响应程序大体应该包含的逻辑步骤:
l 步骤1—— 对Http请求进行初步处理,查找与之对应的Controller处理类(方法) ——HandlerMapping
l 步骤2—— 调用相应的Controller处理类(方法)完成业务逻辑 ——HandlerAdapter
l 步骤3—— 对Controller处理类(方法)调用时可能发生的异常进行处理 ——HandlerExceptionResolver
l 步骤4—— 根据Controller处理类(方法)的调用结果,进行Http响应处理 ——ViewResolver
正是这基于组件、接口的设计,支持了SpringMVC的另外一个特性:行为的可扩展性。