Spring学习笔记3Word文档格式.docx

上传人:b****3 文档编号:18392584 上传时间:2022-12-16 格式:DOCX 页数:29 大小:424.48KB
下载 相关 举报
Spring学习笔记3Word文档格式.docx_第1页
第1页 / 共29页
Spring学习笔记3Word文档格式.docx_第2页
第2页 / 共29页
Spring学习笔记3Word文档格式.docx_第3页
第3页 / 共29页
Spring学习笔记3Word文档格式.docx_第4页
第4页 / 共29页
Spring学习笔记3Word文档格式.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

Spring学习笔记3Word文档格式.docx

《Spring学习笔记3Word文档格式.docx》由会员分享,可在线阅读,更多相关《Spring学习笔记3Word文档格式.docx(29页珍藏版)》请在冰豆网上搜索。

Spring学习笔记3Word文档格式.docx

Proxyproxy=newProxy(landlord);

proxy.rent();

}

1.1.代理对象特征

1.实现和被代理者相同的接口(房东的接口)

2.代替目标对象完成相应的功能。

3.目标方法完成之后,会完成额外的操作。

2.静态代理

场景设计

我们的数据库操作需要事务的控制,addupdatedel等方法都需要添加事务。

例子:

发现问题:

在Servic代码的分离。

1.实现和被代理者相同的接口

2.注入需要的属性

目标对象中的代码只处理业务相关的工作,实现了代码的分离

代理类中的代码:

代理类中的代码

静态代理模式

缺点:

1、一个service对应一个代理类,那么100个service对应100个代理类

2、代理类的每一个方法中都需要填写事务的开启和事务的提交,复用性不高

3、代理类不具备通用性

3.动态代理

3.1.动态代理的种类:

3.2.动态代理的实现

publicclassBeanFactoryProxy{

publicstaticObjectgetProxy(finalObjecttarget,finalTransactionManagertx){

Objectproxy=Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),

newInvocationHandler(){

@Override

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)

throwsThrowable{

Objectresult=null;

StringmethodName=method.getName();

//对于需要添加事务的代码认为进行控制

if(methodName.equals("

add"

)||methodName.equals("

del"

update"

)){

try{

tx.begin();

result=method.invoke(target,args);

mit();

}catch(Exceptione){

tx.rollback();

}

}else{

//不需要添加事务的代码直接执行

result=method.invoke(target,args);

}

returnresult;

}

});

returnproxy;

测试代码:

@Test

publicvoidtest01(){

ApplicationContextcontext=newClassPathXmlApplicationContext("

applicationContext.xml"

//得到目标对象

UserServicetarget=(UserService)context.getBean("

target"

//得到事务对象用来做事务操作

TransactionManagertx=(TransactionManager)context.getBean("

tx"

//得到代理对象

UserServiceuserService=(UserService)BeanFactoryProxy.getProxy(target,tx);

//查看对象的类型

System.out.println(userService.getClass());

userService.find();

动态代理模式优缺点:

优点:

1.实现了代码的分离

2.实现了代码的重复利用,原来每个方法上都需要添加事务,现在只需添加一遍。

缺点:

1.只能处理事务,不具有通用性(日志,安全,权限)

2.使用jdk的动态代理必须实现接口,否则不能生成代理对象。

3.目标类的每个方法都经过判断降低性能。

3.3.Cglib动态代理

不需要实现接口也可以生成代理对象,并且代理对象是目标类的子类

publicclassBeanFactoryProxy{

//第一步:

创建增强器对象

Enhancerenhancer=newEnhancer();

//第二步:

注入目标类的接口

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

//第三步:

设置父类(目标对象)

enhancer.setSuperclass(target.getClass());

//第四步:

enhancer.setCallback(newMethodInterceptor(){

@Override

publicObjectintercept(Objectproxy,Methodmethod,Object[]args,

MethodProxymethodProxy)throwsThrowable{

Objectresult=null;

try{

tx.begin();

method.invoke(target,args);

mit();

}catch(Exceptione){

e.printStackTrace();

tx.rollback();

}

returnresult;

}

});

returnenhancer.create();

4.Spring生成代理对象

说明:

Spring也整合了代理模式

JDK代理实现的接口InvocationHandler

CGLIB代理实现的接口是MethodInterceptor

所以Spring为了代码的服用也进行了接口的抽象MethodInterceptor

是aopalliance.jar这个包下的,spring实现该接口可以自由切换代理模式。

springProxyBean代码如下

//这是一个事物的通知类

publicclassSpringTransactionProxyimplementsMethodInterceptor{

privateTransactionManagertx;

publicvoidsetTx(TransactionManagertx){

this.tx=tx;

publicObjectinvoke(MethodInvocationmethod)throwsThrowable{

try{

tx.begin();

method.proceed();

//如果有下一个通知,继续执行通知,如果没有通知,就会执行目标方法

mit();

}catch(Exceptione){

tx.rollback();

}

returnnull;

配置文件

<

!

--配置目标类-->

beanid="

userDao"

class="

dao.UserDaoImpl"

>

<

/bean>

service.UserServiceImpl"

<

propertyname="

ref="

/property>

--配置通知类-->

transaction.TransactionManager"

txAdvice"

advice.SpringTransactionProxy"

--配置用来产生代理对象的工厂默认使用jdk的代理模式-->

userService"

org.springframework.aop.framework.ProxyFactoryBean"

--1.指明代理需要实现的接口-->

interfaces"

<

list>

<

value>

service.UserService<

/value>

/list>

--2.指明一个目标类-->

targetName"

value="

--<

-->

--3.指名通知类-->

interceptorNames"

txAdvice<

--切换代理模式

proxyTargetClass默认为falsejdk代理模式

proxyTargetClasstruecglib代理模式

-->

proxyTargetClass"

true"

Spring代理工厂的缺点

1.目标陪如果有多个,就会有多个代理类,每个代理类都要重新配置,给配置文件带来了麻烦。

Spring2.5以后就解决的这样的问题

5.SpringAOP面向切面编程

5.1.名词解释

5.1.1.切面(Aspect)

用来完成某些特定功能的类(例如事务处理的类)

切面包括:

日志,安全性处理的类,权限控制,系统中抽象的通用的类。

5.1.2.连接点(JoinPoint):

客户端调用的方法。

5.1.3.通知(Advice):

完成某些特定功能的方法就是通知

 

5.1.4.切入点(PointCut):

If判断条件就是切入点,只有满足切入点,切面才有效,并且通知和目标方法相结合。

5.1.5.目标对象(Target):

正真执行目标方法的类

5.1.6.AOP代理对象(Proxy)

客户端调用都是代理对象

代理对象:

1.jdk的动态代理,要求必须实现接口。

2.cglib的动态代理,不需要实现接口,并且代理对象是目标对象的子类。

5.1.7.织入(Wearing):

代理对象的方法体,用来连接通知和目标对象。

5.2.通知的概念

1.前置通知:

目标方法之前执行的通知接口MehtodInterc

2.后置通知:

目标方法之后执行的通知

3.异常通知:

目标方法抛出异常后执行的通知

4.最终通知:

切面最后执行的通知(必然会执行finally)。

5.环绕通知:

目标方法执行前后执行的通知。

5.3.AOP实现

实现步骤:

1.导入相关jar包

2.编写配置文件的头(导入schema约束)

3.编写目标类

4.编写切面和通知

5.配置切入点表达式

6.配置xml配置文件(关联切面)

5.3.1.导入相关jar包

一共5个jar包

前两个是和Spring整合的jar包,spring依赖第三方的三个jar包。

spring-aop.jar

spring-aspects.jar

aopalliance.jar

aspectjrt.jar

aspectjweaver.jar

5.3.2.AOP配置文件头

?

xmlversion="

1.0"

encoding="

UTF-8"

beansxmlns="

http:

//www.springframework.org/schema/beans"

xmlns:

context="

//www.springframework.org/schema/context"

util="

//www.springframework.org/schema/util"

aop="

//www.springframework.org/schema/aop"

xsi="

//www.w3.org/2001/XMLSchema-instance"

xsi:

schemaLocation=

"

//www.springframework.org/schema/beans

http:

//www.springframework.org/schema/beans/spring-beans-3.2.xsd

//www.springframework.org/schema/context

//www.springframework.org/schema/context/spring-context-3.2.xsd

//www.springframework.org/schema/util

//www.springframework.org/schema/util/spring-util-3.2.xsd

//www.springframework.org/schema/aop

//www.springframework.org/schema/aop/spring-aop-3.2.xsd"

/beans>

5.3.3.添加schema约束

配置方法和之前的相同

5.3.4.编写目标类

publicclassOrderServiceImplimplementsOrderService{

privateOrderDaoorderDao;

publicvoidsetOrderDao(OrderDaoorderDao){

this.orderDao=orderDao;

@Override

publicvoidadd(){

orderDao.add();

publicvoiddel(){

orderDao.del();

publicvoidupdate(){

orderDao.update();

publicvoidfind(){

orderDao.find();

目标类2

publicclassUserServiceImplimplementsUserService{

privateUserDaouserDao;

publicvoidsetUserDao(UserDaouserDao){

this.userDao=userDao;

userDao.add();

userDao.del();

userDao.update();

userDao.find();

5.3.5.编写切面和通知

开关事物具体代码

publicclassTransactionManager{

publicvoidbegin(){

事物开始"

publicvoidcommit(){

事物提交"

publicvoidrollback(){

事物回滚"

通知类具体编辑代码

publicclassTxAdviceimplementsMethodInterceptor{

publicObjectinvoke(MethodInvocationmi)throwsThrowable{

mi.proceed();

5.3.6.切入点表达式

aop:

pointcutexpression="

within(service.*)"

id="

txPointcut"

/>

Within()表达式只能匹配到类级别

Within(包名.类名)只匹配包下的一个类

Within(包名.*)匹配包下的所有类(不包括子包下的)

Within(service..*)匹配这个包下的所有类,包括子孙包

Execution()表达式能匹配到方法级别(具体到方法)

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

例子1:

pointcutexpression=

"

execution(intservice.UserServiceImpl.add())"

改切点表达式表示

返回值为int包名类名serviceUserServiceImpl方法为add()的匹配规则

例子2:

execution(*service.*.add())"

规则:

返回值值任意,包名service下子类的add(),只能包含一层,子孙类不行。

例子3:

pointcut

expression="

execution(*service..*.add())"

方法返回值任意,service包下的所有子孙类的add()

例子4:

execution(*service..*.add(int,String))"

返回值的类型任意service子孙包下的add方法参数类型为int,String

execution(*service..*.add(..))"

id="

返回值类型任意service下的所有子孙类.add方法()(参数任意)

5.3.7.配置xml配置文件

--1.配置目标类-->

orderDao"

dao.OrderDaoImpl"

orderService"

service.OrderServiceImpl"

--2.配置通知类-->

advice.TxAdvice"

prope

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > 交规考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1