首页 > 代码库 > Spring_day03

Spring_day03

代理模式:

 

客户:租一间好的房子(便宜的)

MIS(代理人):找房子,看房子,租房子,交中介费

房东:房东出租房屋。

 

代理模式的特征:

1.代理者(Proxy)必须实现和被代理者(房东)相同的接口(这样看起来才能和被代理者一模一样)

2.在完成客户要求以后,还要做其他的操作(收取中介费)

 

2.静态代理模式(一种思想)

2.1说明:

事务模块是系统开发过程中必不可少的模块。会有专门的团队或负责人来负责。可是一旦事务模块和业务模块交织在一起,就会造成代码的紧耦合。

理想模式:

事务模块的代码只处理事务的方法,而业务模块代码只处理业务,

两者之间最好不要有直接的联系。否则代码的耦合性较高,后期不易于维护和扩展

2.1使用静态代理模式解决紧耦合的问题

 

通过静态代理模式:可以实现业务和事务方法相分离。解决了二者之间的耦合性问题。

问题:虽然能够解决耦合性问题。但是重复代理量较多。每写一个方法都必须添加事务的相关代码。实质上就是代码的迁移,没有做到代码的重用和灵活。代理对象只能代理一个接口。

 

3.动态代理模式 

 

JDK的动态代理

被代理者必须实现接口,如果没有实现接口那么JDK就不能生成代理对象。生成代理对象的速度较快

 

Cglib的动态代理

1.被代理者有无接口都能生成代理对象。

2.生成的代理对象都是被代理者的子类

3.内部生通过二进制码来帮助生成代理对象,所有对象的生成速度很慢。但是一旦生成了代理对象。执行速度很快。

 

4.JDK的动态代理

能够生成代理对象 class形式

class com.sun.proxy.$Proxy6

5.Cglib的动态代理

//增强器

Enhancer enhancer = new Enhancer();

 

//传入接口

enhancer.setInterfaces(target.getClass().getInterfaces());

 

//设置父类   必须

enhancer.setSuperclass(target.getClass());

 

//设置回调

enhancer.setCallback(new MethodInterceptor()

 

CGlib对象的类型

class service.PersonServiceImpl$$EnhancerByCGLIB$$ea3089c1

 

Spring内部集成了Cglib

 

 

6.SpringAOP

面向切面编程 一种思想 

6.1名词解释

1.切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象。

一个切面就是在完成目标方法后再执行其操作的程序代码

 

2.连接点(Joinpoint):在程序执行过程中某个特定的点

就是客户端调用的目标方法。

 

3.通知(Advice):在切面的某个特定的连接点上执行的动作。

就是切面中的方法。

 

4.切入点(Pointcut):匹配连接点的断言

切入点就是一个匹配切面的过程

 

5.目标对象(Target Object) 被一个或者多个切面所通知的对象。

就是真正执行目标方法的对象

 

6.织入(Weaving):把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。

形成切面的过程就是织入。

6.2AOP的入门

步骤:

1.配置头文件 导入约束

 xmlns:aop="http://www.springframework.org/schema/aop"

2.导入相关的开发jar5

 

3.配置自定义的切面

 

4.xml配置的顺序

Content Model : (pointcut*, advisor*, aspect*)

 <aop:config>

            <!--配置切入点  -->

            <aop:pointcut expression="within(service.*)" id="pc"/>

            <aop:aspect ref="myAspect">

                    <!--配置通知的方法  -->

                    <aop:around method="around" pointcut-ref="pc"/>

            </aop:aspect>

 

    </aop:config>

 

6.3AOP的原理

当创建对象的时候首先spring和和切入点表达式进行匹配。如果匹配成功。则创建代理对象。我们客户端拿到代理对象后看上去和目标对象一模一样。//????

调用目标对象执行方法。就会执行切面中的通知(方法)。利用代理对象完成一些额外的操作。最终执行目标方法。

 

6.4:通知的类型

1.环绕通知(Around Advice):在目标方法执行之前。执行之后都需要执行额外操作的通知。

2.前置通知(Before advice):在目标方法执行之前的操作。

3.后置通知(After returning advice):在目标方法执行之后执行的通知

4.异常通知(After throwing advice):在执行目标方法如果目标方法报错就会被异常通知拦截,这时异常通知才会执行。

5.最终通知(After (finally) advice):不管如何都会执行最终通知。

 

6.5 异常的处理

Spring中异常的try--catch不能随便加,如果添加了try-catch那么spring容器就捕获不到。不能做出正确的处理。如果想写try-catch那么异常捕获时要具体指明某一类的异常 不能使用Exception,因为这个异常捕获能力太强。

6.6通知的处理顺序

当目标方法执行抛出异常时 异常通知会被执行,后置通知不会被调用。

 

6.7通知的使用场景

1.环绕通知:我是不需要目标方法执行,并且执行前后有必要的操作。

2.前置通知:日志收集????? 前置通知执行不能影响目标方法是否被执行 与它毫无关系。

3.后置通知:如果需要对目标方法的返回值结果做操作 可以使用后置通知。通知也不能影响目标方法的执行。

4.异常通知:可以对异常做收集 以后使用异常通知。

5.最终通知:可以用来关闭一些链接或者释放资源。

 

6.8通知中的参数

除了环绕通知之外其他的通知都是JoinPoint。并且所有的参数都必须位于第一位。

而环绕通知中 必须添加ProceedingJoinPoint 因为 只有ProceedingJoinPoint类中有proceed方法。才能让目标方法执行。

6.9关于表达式的写法

within(service.*) 

它是一个类级别的表达式,可以按照类型来匹配。匹配的规则包名+类名。

如果想匹配该包下的所有子类 *代替。 如果想匹配该包下的所有子孙类用

..*表示。

 

execution(返回值结果 包名.类名.方法名(参数名))

execution(* service..*(..))

表达式创建代理对象的原理;

只有满足表达式要求的才会被创建代理对象,能够精确到方法和参数级别。

 

Spring_day03