Spring个人学习笔记.docx
《Spring个人学习笔记.docx》由会员分享,可在线阅读,更多相关《Spring个人学习笔记.docx(34页珍藏版)》请在冰豆网上搜索。
![Spring个人学习笔记.docx](https://file1.bdocx.com/fileroot1/2023-2/6/b4f0fecc-b90a-4a1f-a5d6-7e8e5af7d736/b4f0fecc-b90a-4a1f-a5d6-7e8e5af7d7361.gif)
Spring个人学习笔记
Spring_beginning
Spring最常用的特性
³利用Spring来创建对象(JavaBean工厂)
³利用Spring构建业务逻辑层
²管理依赖关系
²适应需求变更
³利用Spring创建数据访问对象(DAO)
³利用Spring进行事务处理
环境搭建
1、spring依赖库
*SPRING_HOME/dist/spring.jar
*SPRING_HOME/lib/jakarta-commons/commons-logging.jar
*SPRING_HOME/lib/log4j/log4j-1.2.14.jar
2、拷贝spring配置文件到src下
applicationContext.xml
3、拷贝log4j配置文件到src下
log4j.properties
4、在UserManagerImpl中提供构造函数或setter方法,spring将实例化好的UserDao实现注入给我们
5、让spring管理我们的对象创建和依赖,必须在spring配置中进行定义
--构造方法注入
-->
--这种依赖关系,被放到了配置文件中,这样,只要需求有变更,只需要修改这种依赖关系即可,java代码本身不用任何变更-->
6、编写客户端
//获取BeanFactory
BeanFactoryfactory=
newClassPathXmlApplicationContext("applicationContext.xml");
//从容器中获取userManager对象
UserManageruserManager=(UserManager)factory.getBean("userManager");
userManager.save("伟超","1234");
springIoc容器的关键点:
*必须将被管理的对象定义到spring配置文件中
*必须定义构造函数或setter方法,让spring将对象注入过来
³只需改动ApplicationContext.xml的配置,即可实现实际功能的切换
IOC/DI
³控制反转(InversionofControl,IoC)与依赖注入(DependencyInjection)
³由容器来管理对象之间的依赖关系(而不是对象本身来管理),就叫“控制反转”或“依赖注入”
³以上代码,已清楚阐述IOC/DI出现的原因,以及IOC的基本原理
³Spring框架的基本思想就是IOC/DI
³Spring就是一个IOC容器
³IOC与DI,说的是一回事,但DI这个名词更能表达这种设计模式的思想
依赖注入的类型
³构造器注入
²通过类的构造方法注入依赖关系
³设值方法注入
²通过类的setter方法注入依赖关系
³第三种:
接口注入(不常用)
²定义一个注入接口,在需要注入的类中实现此接口,由于这种方法具有侵入性,所以不常用
2.Injection
2.1spring的普通属性注入
参见:
spring文档3.3章节
2.2什么是属性编辑器,作用?
2.2.1自定义属性编辑器
自定义属性编辑器:
spring配置文件中的字符串转换成相应的对象进行注入
心得:
从此处可以看出,spring里面输入的都是字符串,但是可以更根据POJO设置的类型做相应的转换
spring已经有内置的属性编辑器,我们可以根据需求自己定义属性编辑器
2.2.2如何定义属性编辑器?
①继承PropertyEditorSupport类,覆写setAsText()方法,参见:
UtilDatePropertyEditor.java
SimpleDateFormatsdf=newSimpleDateFormat(format);
setValue(d);
②将属性编辑器注册到spring中,参见:
applicationContext-editor.xml
yyyy/MM/dd
2.3依赖对象的注入方式
*ref属性
*[标签]
*内部来定义
如何将公共的注入定义描述出来?
*通过标签定义公共的属性,指定abstract=true
*具有相同属性的类在标签中指定其parent属性
参见:
applicationContext-other.xml
2.4springBean的作用域:
scope可以取值:
*singleton:
每次调用getBean的时候返回相同的实例
*prototype:
每次调用getBean的时候返回不同的实例
3Spring对AOP(AspectOrientedProgramming)的支持
3.1AOP相关
AOP的关注点是Crosscuttingconcern,比如下面的检查安全性,在通过配置关注点,可以不影响主程序,Aspect包含Pointcut(切入点注册)和advice(具体怎么切、实现)
3.2采用Annotation的方式
3.3.1spring依赖库
*SPRING_HOME/dist/spring.jar
*SPRING_HOME/lib/jakarta-commons/commons-logging.jar
*SPRING_HOME/lib/log4j/log4j-1.2.14.jar
*SPRING_HOME/lib/aspectj/*.jar
SecurityHandler.java(2、3、4)
3.3.2采用Aspect定义切面
@Aspect
publicclassSecurityHandler{
@Pointcut("execution(*add*(..))")
privatevoidallAddMethod(){};
@Before(value="allAddMethod()")
privatevoidcheckSecurity(){
System.out.println("----------checkSecurity()---------------");
}
}
3.3.3在Aspect定义Pointcut和Advice
/**
*定义Pointcut,Pointcut的名称就是allAddMethod,此方法不能有返回值和参数,
*该方法只是一个标识
*Pointcut的内容是一个表达式,描述那些对象的那些方法(订阅Joinpoint)
*/
@Pointcut(value="execution(*add*(..))")
privatevoidallAddMethod(){};
/**
*定义Advice,标识在那个切入点何处织入此方法
*/
@Before(value="allAddMethod()")
privatevoidcheckSecurity(){
System.out.println("----------checkSecurity()---------------");
}
3.3.4、启用AspectJ对Annotation的支持并且将Aspect类和目标对象配置到Ioc容器中
aspectj-autoproxy/>
即Advice中通过方法名引用这个切人点
Client.java
UserManageruserManager=(UserManager)factory.getBean("userManager");
AOP:
//这两个方法执行之前就会执行advice;
userManager.addUser("张三","123");
userManager.deleteUser(123);
*Crosscuttingconcern
*Aspect
*Advice
*Pointcut
*Joinpoint
*Weave
*TargetObject
*Proxy
*Introduction
3.3采用静态配置文件
config>
aspectid="sercurity"ref="sercurityHandler">
pointcutid="allAddMethod"expression="execution(*com.bjsxt.spring.UserManagerImpl.add*(..))"/>
beforemethod="checkSecurity"pointcut-ref="allAddMethod"/>
aspect>
config>
3.4JointPoint参数介绍
Aspect默认情况下不用实现接口,但对于目标对象(UserManagerImpl.java),在默认情况下必须实现接口,如果没有实现接口必须引入CGLIB库
我们可以通过Advice中添加一个JoinPoint参数,这个值会由spring自动传入,从JoinPoint中可以取得参数值、方法名等等
privatevoidcheckSecurity(JoinPointjp){
Object[]args=(Object[])jp.getArgs();
3.5JDK动态代理和CGLIB字节码生成(弱)
1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
如何强制使用CGLIB实现AOP?
*添加CGLIB库,SPRING_HOME/cglib/*.jar
*在spring配置文件中加入aspectj-autoproxyproxy-target-class="true"/>
JDK动态代理和CGLIB字节码生成的区别?
*JDK动态代理只能对实现了接口的类生成代理,而不能针对类
*CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
因为是继承,所以该类或方法最好不要声明成final
importjava.lang.reflect.InvocationHandler;
importjava.lang.reflect.Method;
importjava.lang.reflect.Proxy;
publicclassSecurityHandlerimplementsInvocationHandler{
privateObjecttargetObject;
publicObjectnewProxy(ObjecttargetObject){
this.targetObject=targetObject;
returnProxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),
this);
}
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)
throwsThrowable{
checkSecurity();
Objectret=null;
try{
ret=method.invoke(this.targetObject,args);
}catch(Exceptione){
e.printStackTrace();
thrownewjava.lang.RuntimeException(e);
}
returnret;
}
privatevoidcheckSecurity(){
System.out.println("----------checkSecurity()---------------");
}
}
publicclassClient{
publicstaticvoidmain(String[]args){
//UserManageruserManager=newUserManagerImpl();
SecurityHandlerhandler=newSecurityHandler();
UserManageruserManager=(UserManager)handler.newProxy(newUserManagerImpl());
//userManager.addUser("张三","123");
userManager.deleteUser
(1);
}
}
4Spring+Hibernate
4.1采用编程式事务
参照:
Spring_Hibernate1
1、getCurrentSession()与openSession()的区别?
线程绑定
session在commit或rollback时会自动关闭
getCurrentSession()
绑定到当前线程
自动关闭
openSession()
不会有绑定
必须手动关闭
2、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
*如果使用的是本地事务(jdbc事务)
thread
*如果使用的是全局事务(jta事务)
jta
4.2采用声明式事务
4.2.1声明式事务配置
通过配置把Hibernate里面的事务管理(session)交给Spring以注入的方式完成
①配置SessionFactory
注入到Spring和Hibernate做集成的响应的类里面,——创建sessionFactory
classpath:
hibernate.cfg.xml
②配置事务管理器
③事务的传播特性
adviceid="txAdvice"transaction-manager="transactionManager">
attributes>
methodname="add*"propagation="REQUIRED"/>
methodname="del*"propagation="REQUIRED"/>
methodname="modify*"propagation="REQUIRED"/>
methodname="*"read-only="true"/>
attributes>
advice>
④那些类那些方法使用事务(事务边界)
config>
pointcutid="allManagerMethod"
expression="execution(*com.tongji.usermgr.manager.*.*(..))"
/>
advisorpointcut-ref="allManagerMethod"advice-ref="txAdvice"/>
config>
4.2.2编写业务逻辑方法
*继承HibernateDaoSupport类,使用HibernateTemplate来持久化,HibernateTemplate是HibernateSession的轻量级封装
publicclassLogManagerImplextendsHibernateDaoSupport
implementsLogManager{
publicvoidaddLog(Loglog){
getHibernateTemplate().save(log);
}
}
*把LogManagerImpl,UserManagerImpl,注入Spring配置文件
*默认情况下运行期异常才会回滚(包括继承了RuntimeException子类),普通异常是不会滚的,但是Spring可以自己配置哪些异常回滚,哪些不回滚
*编写业务逻辑方法时,最好将异常一直向上抛出,在表示层(struts)处理
*关于事务边界的设置,通常设置到业务层,不要添加到Dao上
4.2.3了解事务的几种传播特性
1.PROPAGATION_REQUIRED:
如果存在一个事务,则支持当前事务。
如果没有事务则开启
2.PROPAGATION_SUPPORTS:
如果存在一个事务,支持当前事务。
如果没有事务,则非事务的执行
3.PROPAGATION_MANDATORY:
如果已经存在一个事务,支持当前事务。
如果没有一个活动的事务,则抛出异常。
4.PROPAGATION_REQUIRES_NEW:
总是开启一个新的事务。
如果一个事务已经存在,则将这个存在的事务挂起。
5.PROPAGATION_NOT_SUPPORTED:
总是非事务地执行,并挂起任何存在的事务。
6.PROPAGATION_NEVER:
总是非事务地执行,如果存在一个活动事务,则抛出异常
7.PROPAGATION_NESTED:
如果一个活动的事务存在,则运行在一个嵌套的事务中.如果没有活动事务,
则按TransactionDefinition.PROPAGATION_REQUIRED属性执行
4.2.4Spring事务的隔离级别
1.ISOLATION_DEFAULT:
这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
另外四个与JDBC的隔离级别相对应
2.ISOLATION_READ_UNCOMMITTED:
这是事务最低的隔离级别,它