您的位置:首页 > 编程语言 > Java开发

Spring学习第二天

2015-12-25 11:58 423 查看

4、面向切面编程

4.1、代理模式

代理模式的英文叫做Proxy或Surrogate,中文都可译为“代理”,所谓代理就是一个人或一个机构代表另一个人或机构采取行动。在一些情况下,一个人客户不想或者不能够直接引用一个对象;而代理对象可以在客户端和目标对象之间起到中介作用。
A、抽象主题角色
声明了真实主题和代理主题的共同接口,这样在任何可以使用真实主题的地方使用代理主题。
B、代理主题(Proxy)角色
代理主题内部含有对真实主题的引用,从而可以在任何时候操作真实主题。代理主题角色提供   了一个与真实主题角色相同的接口,以便在任何时候都可以替代真实主题控制对真实主题的引用,负责在需要的时候创建真实主题对象(和删除真实主题对象);代理角色通常在将客户端调用传递给真实主题之前或之后,都要执行某个操作,而不是单纯的将其调用传递给真实对象。
C、真实主题对象
定义了代理角色所代表地真实对象
![各主题之间关系](http://img.blog.csdn.net/20151225115727205)


4.1.1、JDK动态代理





JDK的动态代理必须具备四个条件:

目标接口、目标类、拦截器、代理类。

总结:

1、因为利用JDKProxy生成的代理类实现接口,所有目标类中所有方法在代理类中都有。

2、生成的代理类的所有的方法都拦截了目标类的所有方法。而拦截器中invoke方法的内容正好就是代理类的各个方法的组成体。

3、利用JDKProxy方式必须有接口的存在。

4、invoke方法中的三个参数可以访问目标类的被调用方法的API、被调用方法的参数、被调用方法的返回类型。

4.1.2、CGLIB做代理

1、CGLib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展java类与实现java接口。

2、用CGLib生成代理类是目标类的子类。

3、用CGLib生成代理类不需要接口。

4、用CGLib生成的代理类重写了父类的各个方法。

5、拦截器中的intercept方法内容正好就是代理类的方法体。





Spring两种代理方式:

1、如目标对象实现了若干接口,Spring使用JDK的java.lang.reflect.Proxy类代理。

优点:因为有接口,所以使系统更加松耦合。

缺点:为每一个目标类创建接口。

2、若目标对象没有实现任何接口,Spring使用CGLib库生成目标对象的子类。

优点:因为代理类与目标类是继承关系,所以不需要有接口的存在。

缺点:因为没有使用接口,所有系统的耦合性没有使用JDK的动态代理好。

4.1.3、Spring的动态代理

1、拦截器必须实现MethodInterceptor接口

2、在Spring中配置



总结:不管采用JDK动态代理生成还是采用CGLib生成动态代理类。目标类的所有方法都被拦截下来。而在哪个方法里做比如权限的判断、安全性的检测等一系列工作必须在拦截器中做相应判断。但是这样的编程给程序员带来一定的麻烦。

1、在拦截器中控制哪些方法将被做权限判断、安全性检测等是一件比较困难的事情。

A、采用这样的配置目标类只能是一个,所以如果用这种方法做 权限控制,得写很多代理,给代码的书写造成困难。

B、每个类的每个方法如果都有不同的权限(往往是这样),在拦截器中的判断代码书写会很困难。

2、这样的代码会导致硬编码,也就是说我们必须在拦截器中书写一些权限判断等事情,会导致拦截器中代码量增大,造成维护的麻烦。

4.2AOP编程

4.2.1、概念

A、Aspect(切面)

比如说事务、权限等,与义务模块没有关系的部分。

B、Joinpoint(连接点)

目标类的目标方法。(有客户端在调用的时候决定)

C、Pointcut(切入点)

指我们要对那些拦截的方法的定义。被纳入Spring Aop中的目标类的方法。

D、Advice(通知)

指拦截到Joinpoint之后所要做的事情就是通知,通知分为前置通知、后置通知、异常通知、最终通知、环绕通知(切面要完成的功能)。

E、Target(目标对象)

代理的目标对象。

F、Weaving织入

指把切面应用到目标对象来创建新的代理对象的对象,切面在指定的连接点织入到目标对象。

通知根据拦截目标类中的方法的位置不一样可以分为:前置、后置、最终、环绕、异常通知。

4.2.2、AOP实现的两种模式

1、XML形式

A、前置通知

在spring配置文件中声明切面

在spring配置文件中声明目标类

定义切面、切入点、通知

其它通知参考上。

2、Aop注解形式

为了在Spring配置中使用@AspectJ切面,首先必须启动对@AspectJ切面配置的支持,并确保自动代理

5、Spring数据库

5.1、Spring+JDBC

1、Jdbc编程特点
静态代码+动态遍历 = jdbc编程。在Spring中动态变量可以用注入的形式给予。这样的编程方式适合包装成模板。静态代码构成了模板,而动态变量则是需要传人的参数。
2、引入DataSource
在Spring中注入DataSource
3、核心类JdbcTemplate
A、基于模板的设置
B、完成了资源的创建和释放工作
C、简化我们队jdbc的操作
D、完成了对jdbc的核心流程的工作,包括sql语句的创建和执行
E、仅需要传递DataSource就可以把它实例化
F、JdbcTemplate只需要创建一次
G、JdbcTemplate是线程安全类
4、使用JdbcTemplate
在Dao类中,使用JdbcTemplate作为属性,用Spring对JdbcTemplate进行注入。再对JdbcTemplate进行DataSource注入。
5、继承JdbcDaoSupport
在Dao类中,继承JdbcDaoSupport。因为JdbcDaoSupport已经有了JdbcTemplate的引用,所以只要继承JdbcDaoSupport就相当于有了JdbcTemplate属性。
6、使用properties文件
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>jadb.properties</value>
</list>
</property>
</bean>
7、RowMapper的使用
A、产生原因:在Jdbc的操作中,有很多情况下是要将ResultSet里的数据封装到一个持久化Bean里,再把持久化Bean封装到集合中。这样会造成大量的代码的重复,不利于代码重用。而RowMapper正好解决这个问题。
B、使用:
写一个类实现RowMapper接口(在回调方法中使用this.getJdbcTemplate().query(sql,new ...Mapper()))或在方法上定义一个匿名内部类。
8、声明式事务管理
Spring的事务管理器
Spring没有直接管理事务,而是将管理事务的责任委托给JTA或相应的持久性机制所提供的某个特定平台的事务实现。
A、事务管理器实现:org.springframework.jdbc.datasource.DataSourceTransactionManager;
目标:在单一的JDBC DataSource中的事务管理。
B、事务管理器实现:org.springframework.orm.hibernate3.HibernateTransactionManager;
目标:当持久化机制是Hibernate时,用它来管理事务。
C、事务管理器实现:org.springframework.jdo.jdoTransactionManager;
目标:当持久化为jdo时,用它来管理事务。
D、事务管理器实现:org.springframework.transaction.jta.JtaTransactionManager;
目标:使用一个Jta实现来管理事务,在一个事务跨越多个资源时必须使用。
E、事务管理器实现:org.springframework.orm.ojb.PersistenceBrokerTranctionManager;
目标:当apache的ojb用作持久化机制时,用它来管理事务。
Spring事务的传播属性
A、PROPAGATION_REQUIRED:业务需要在一个事务中运行,如果方法运行时,已经处在一个事务中,那么加入该事物,否则为自己创建一个新事务。
B、PROPAGATION_NOT_SUPPORTED:声明方法不需要事务,如果方法没有关联一个事务,容器不会为它开启事务,如果方法在一个事务中被调用,该事物会被挂起,在方法结束后,原来的事务便会恢复执行。
C、PROPAGATION_REQUIRES_NEW:不管是否存在事务,业务方法总会为自己发起一个新的事务,如果方法已经运行在一个事务中,则原有事务会被挂起,新的事务会被创建,知道方法被执行结束,新事务才算结束,原先的事务才会恢复执行。
D、PROPAGATION_MANDATORY:该属性表明方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务,如果业务方法在没有事务的环境下调用,容器就会抛出例外。
E、PROPAGATION_SUPPORTS:如果事务方法在某一事务范围内被调用,则该方法成为该事务的一部分,如果在事务外被调用,则方法在没有事务的环境下执行。
F、PROPAGATION_NEVER:业务方法不在任何事务中执行,如果在某个事务下执行就会抛出例外,只有业务方法没有关联任何事务时,才能正常执行。
G、PROPAGTION_NESTED:如果一个活动的存在,则运行在一个嵌套的事务中,如果没有活动事务,则按PROPAGATION_REQUIRED属性执行,它使用一个单存的事务,这个事务拥有多个可以回滚的保存点,内部事务的回滚不会对外部事务造成影响,它只对DataSourceTransaction事务管理器起效。
Spring事务的隔离级别
A、DEFAULT:使用后端默认的隔离级别。
B、READ_UNCOMMITED:允许读取还未提交的改变的数据。可能导致脏、幻、不可重复读。
C、READ_COMMITED:允许在并发事务已经提交后读取,可防止脏读,但幻读和不可重复读仍能可发生。
D、REPEATABLE_READ:对相同字段的所次读取是一致的,除非数据被事务本身改变,可防止脏读、不可重复读,但仍可能幻读。
E、SERIALIZABLE:完全服从ACID的隔离级别,这是所有事务隔离最慢的,它是经典的通过完全锁定在事务中设计的数据表来完成的。


Spring学习第一天:/article/11030677.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: