深入浅出 Spring

Posted crawl+

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入浅出 Spring相关的知识,希望对你有一定的参考价值。

原创播客,如需转载请注明出处。原文地址:http://www.cnblogs.com/crawl/p/7683070.html  

前言:笔记中提供了大量的代码示例,需要说明的是,大部分代码示例都是以图片的形式展示的,所有的图片都是来自本人所敲代码的截图,不足之处,请大家指正~

第一部分:环境搭建及 IOC 容器

一、Spring 环境在 Eclipse 中的搭建及配置

1、点击 Help --> Install New SoftWare --> Add -->Archive

2、导入 spring-tool-suite-3.6.4.RELEASE-e4.4.2-win32-x86_64.zip 压缩包 选择带有 Spring IDE 的项,进行安装即可

3、导入所需要的 jar 包

> spring 所依赖的日志 jar包 apache-commons\\commons-logging-1.1.1.jar

> spring 自身的 jar包  spring-framework-4.0.0.RELEASE\\libs 目录下的 4 个 jar 包,见下:

> 或者导入     (此处的 log4j 意为 log for java)

注:日志的规范:spring-framework-3.0.2.RELEASE-dependencies\\org.apache.log4j\\com.springsource.org.apache.log4j\\1.2.15

日志的实现:spring-framework-3.0.2.RELEASE-dependencies\\org.apache.commons\\com.springsource.org.apache.commons.logging\\1.1.1

补:还要把 log4j.properties 文件拷贝到类路径(src)下

二、Spring 的 IOC(Inverse of  Control   控制反转):将对象创建的权利反转给 Spring 框架

1、IOC 的 Helloworld

1)创建一个接口 UserService,定义一个抽象方法  public void sayHello();

2)创建接口的实现类 UserServiceImpl,实现接口的抽象方法

public void sayHello(){

  System.out.println("Hello Spring...");

}

3)创建 Spring bean 管理的配置文件:  applicationContext.xml 

测试:

注:Spring 在调用 ClassPathXmlApplicationContext() 方法加载applicationContext.xml 文件时,就创建相应的 bean 的实例了!

2、IOC 的核心配置文件  applicationContext.xml

bean 节点的:

  id 属性:标志一个唯一的 Bean,id属性值必须唯一;必须以字母开始,可以使用字母、数字、连字符、下划线、句话、冒号  id:不能出现特殊字符

  class属性: Bean 的全类名

  scope属性: 代表 Bean 的作用范围     可取值:

    >* singleton:单例的,默认值

    >* prototype:多例的,Spring 整合 Struts2 时,Action 类交给 Spring 管理,需要配置为 prototype

    > requese:WEB项目中,Spring创建一个Bean的对象,将对象存入到request域中,和 request 周期一致

    > session:WEB项目中,Spring创建一个Bean的对象,将对象存入到session域中,和 session 周期一致

    > golbalSession:WEB项目中,应用在Porlet环境.如果没有Porlet环境那么globalSession相当于session.

  init-method属性:作为 Bean 初始化时执行的方法

  destroy-method属性:作为 Bean 被销毁时执行的方法

三、Spring 的 依赖注入(DI:Dependency Injection):在 Spring 框架负责创建 Bean对象时,动态的将依赖对象注入到 Bean 组件中

1.两种依赖注入的方式:

注:进行依赖注入,不管是值类型的属性,还是引用类型的属性,在对应的 bean 中必须创建对应的属性,并提供 setter 方法(注解注入的情况除外

测试: 常规调用即可

2.构造器方式注入属性

1) 注入引用类型的属性

    > 构造 Car

> 配置 bean

2)注入引用类型的属性

> 创建 Person 类,添加 Car 引用

> 配置 bean

3.注入数组和集合类型的属性

1)注入 数组 和 List 集合的属性,使用 list 节点(在 property 节点中)

2)注入 Map 集合类型的属性,使用 map 节点 entry 节点配置

注:Set 集合的配置方式与 Map 集合类似,其使用  set 节点配置

3)注入 Properties 集合类型的属性 使用 props 和 prop 节点配置

注:需要在 类中定义以上这些集合类型的属性,再添加  setter 方法

补: Spring 的多个配置文件开发:

            > 在一个配置文件中包含另一个配置文件(较常使用):

                      <import resource="applicationContext2.xml"></import>

> 创建工厂的时候加载多个配置文件(较少使用):

 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml");

四、Spring 整合 Web

1.导入 所需的 jar 包:E:\\jar包开源框架-新\\spring-framework-4.2.4.RELEASE\\libs 目录下的 spring-web-4.2.4.RELEASE.jar

2.在 web.xml 中配置 listener 监听器,此监听器为 ServletContextListener 在 容器加载时就会创建,所以在 IOC 容器中的实例也在Web容器加载时就被创建,且只被创建一次

3.修改以前的工厂代码,改为使用 WebApplicationContext 的方式

 

五、IOC 注解方式

1. 搭建使用环境:

①引入所需的aop jar 包, spring-framework-4.2.4.RELEASE\\libs\\spring-aop-4.2.4.RELEASE.jar

②引入 context 约束:spring-framework-4.2.4.RELEASE\\docs\\spring-framework-reference\\html\\xsd-configuration.html 中复制即可

开启注解的扫描

2.使用注解:

1)这里使用的是 @Component 组件

测试与常规的工厂一样

补:@Component 有三个衍生注解:

@Controller :使用在 WEB 层

@Service : 使用在业务层

@Repository :使用在持久层

注:这三个注解是为了让标记类本身的用途清晰,功能目前和 @Component 一致

2)使用 @Value 注解注入基本数据类型的属性

 

3)注入引用类型的属性

方式一:使用 @Autowired  和 @Qualifier

 

方式二:使用 Java 提供的 @Resource 注解

4)使用注解设置 Bean 的作用范围

在类的上方设置 @Scope(value="prototype") 可取值:singleton 、 prototype

 

5)Bean的生命周期的设置(为方法添加)  了解即可

@PostConstruct  的作用相当于 init-method

@PreDestroy 的作用相当于 destroy-method

 

六、Spring 整合 JUnit 单元测试,方便测试

1.导入所需的 spring-test-4.2.4.RELEASE.jar jar 包 spring-framework-4.2.4.RELEASE\\libs\\spring-test-4.2.4.RELEASE.jar

2.为单元测试类添加注解:

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("classpath:applicationContext.xml")

3.使用:

第二部分:Spring 的 AOP

一、AOP 概述

1. AOP:Aspect Oriented Programming   意为面向切面编程

2. AOP 采取横向抽取机制,取代了传统横向继承体系的重复性代码,主要可以实现:性能监视、事务管理、安全检查、缓存 等功能

3. 优点:可以在不修改源代码的前提下,对程序进行增强

二、AOP 的底层实现

1.基于 JDK 的动态代理:针对实现了接口的类产生代理   实例代码(代码了解即可):

> 定义 UserDAO(接口) 和 UserDaoImpl(实现类) 类,创建 save() 和 update() 两个方法

> 定义代理类:

2.Cglib 动态代理:针对没有实现接口的类产生代理. 应用的是底层的字节码增强的技术 生成当前类的子类对象.实例代码(代码了解即可):

> 定义 BookDaoImpl 类,创建 save()  和 update()  方法

> 创建代理类

 

三、AOP开发的相关术语

1. Joinpoint(连接点): 所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点.

2. Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义.

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

4.Introduction(引介):(知道即可)引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.

5.Target(目标对象):代理的目标对象 如:BookDaoImpl    UserDaoImpl

 6.Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程.也就是:生成某个类代理对象的过程

7.Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类。也就是:生成的代理对象

8.Aspect(切面): 是切入点和通知(引介)的结合。需要我们自己来编写和配置(通知需要自己来编写,切入点需要配置) 切面: 切入点 + 通知

四、AspectJ 的 XML 方式的 AOP的具体开发

1.环境配置

1)导入所需的 jar 包

* spring 框架开发的基本 jar 包

* spring 的传统AOP的开发的包

spring-aop-4.2.4.RELEASE.jar

com.springsource.org.aopalliance-1.0.0.jar

(spring-framework-3.0.2.RELEASE-dependencies\\org.aopalliance\\com.springsource.org.aopalliance\\1.0.0)

* aspectJ 的开发包:

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

(spring-framework-3.0.2.RELEASE-dependencies\\org.aspectj\\com.springsource.org.aspectj.weaver\\1.6.8.RELEASE)

spring-aspects-4.2.4.RELEASE.jar

2)向 applicationContext.xml 中配置约束

 2.具体使用:

准备:定义接口:CustomerDao,创建 save() 和 update() 方法

定义实现类:CustomerDaoImpl

定义测试方法:

 

1)创建切面类:

2)applicationContext.xml 文件中配置 AOP

补:关于 AOP 切入点的表达式:

补:关于 AOP 的通知类型

>前置通知(aop:before):在目标类的方法执行之前执行

>最终通知(aop:after):在目标类的方法执行之后执行,若程序出现异常,通知也会执行

> 后置执行(aop:after-returning):在目标类的方法正常执行后再执行

> 异常抛出通知(aop:after-throwing):在目标类抛出异常后通知

>环绕通知(aop:around):目标类方法执行前后都通知

注:特别注意 环绕通知 :

五、Spring 框架的 AOP 技术------注解的方式

1.环境准备

1)引入相关的 jar 包,见模块四

2)引入相关的约束 spring-3 的 applicationContext.xml 文件的约束已全面

 3)① 定义接口:CustomerDao,创建 save() 和 update() 方法 ② 定义实现类:CustomerDaoImpl ③创建测试方法

4)编写切面类 MyAspectAnno,并在 applicationContext.xml文件中配置切面类

 

 5)AOP 注解的入门操作:

> 在 applicationContext.xml 里配置开启 AOP 注解的自动代理

> 在切面类中设置注解

2. AOP注解的通知类型和通用切入点

1)通知类型:

    * @Before :前置通知

    * @AfterReturing :后置通知

    * @Around :环绕通知(默认目标对象的方法不执行)

    * @After :最终通知

    * @AfterThrowing :异常抛出通知.

2)演示:

补:配置通用的切入点

六、Spring 的 JDBC 模板技术

1.环境的配置 -- 导入所需的 jar 包和 配置文件

还需要:

2.使用 Spring-JDBC 的模板类  JdbcTemplate

> 不使用 IOC 容器管理,手动 new 出 JdbcTemplate 对象的方式,使用的是 Spring 框架内置的数据库连接池 DriverManagerDataSource

 

> 使用 IOC 容器管理管理数据源

① 在 applicationContext.xml 文件中配置数据库连接池(Spring 内置)和 JdbcTemplate

②使用:

3.使用 Spring 框架管理开源的数据库连接池

1)管理 DBCP 数据库连接池

> 导入所需的 2个 jar 包,在 Spring 的依赖包中找

spring-framework-3.0.2.RELEASE-dependencies\\org.apache.commons\\com.springsource.org.apache.commons.dbcp\\1.2.2.osgi\\com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar

spring-framework-3.0.2.RELEASE-dependencies\\org.apache.commons\\com.springsource.org.apache.commons.pool\\1.5.3\\com.springsource.org.apache.commons.pool-1.5.3.jar

 

> 在 applicationContext.xml 中配置 DBCP 数据库连接池

 2)管理 C3P0 数据库连接池

> 导入所需的 jar 包  在 Spring 的依赖包中找

spring-framework-3.0.2.RELEASE-dependencies\\com.mchange.c3p0\\com.springsource.com.mchange.v2.c3p0\\0.9.1.2\\com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar

> 在 applicationContext.xml 中配置  C3P0 数据库连接池

4、 JDBC模板类的使用--- 增 删 改 查

1) 增 删 改 操作

 

2)查询一条记录 使用  queryForObject() 方法

 

自定义实现类,先定义一个 JavaBean:Account,然后:

 

3)查询一组记录的 List,使用 query() 方法

 

七、Spring 的事务管理

1. Spring 事务管理的相关 API

1)PlatformTransactionManager 接口-----平台事务管理器(真正管理事务的类,该接口有具体的实现类(DataSourceTransactionManagerHibernateTransactionManager),根据不同的持久层框架,需要选择不同的实现类)

2)TransactionDefinition  接口----事务定义信息,如:事务的隔离级别、传播行为、超时信息、是否只读

补:事务的传播行为常量(常用):

 * 保证同一个事务中

PROPAGATION_REQUIRED   支持当前事务,如果不存在 就新建一个(默认,较常使用)

* 保证没有在同一个事务中

PROPAGATION_REQUIRES_NEW    如果有事务存在,挂起当前事务,创建一个新的事务 

*PROPAGATION_NESTED  如果当前事务存在,则嵌套事务执行

3)TransactionStatus 接口 ------ 事务的状态

2.案例:转账环境的搭建

1)导入所需的 jar 包

IOC:6个包  AOP:4个 整合JUnit:1个 c3p0:1个 jdbc:2个 mysql驱动:1个    导入配置文件(2个)

2)编写 AccountService、AccountDao 接口,及其实现类 AccountServiceImpl、AccountDaoImpl 详见 spring-3-tx 项目

3)JdbcDaoSupport 类:若继承该类便可通过 getJdbcTemplate() 方法获取 JdbcTemplate 对象,具体获取方法:

① 因为 JdbcDaoSupport中存在属性 JdbcTemplate,所以直接在 applicationContext.xml 文件中配置 JdbcTemplate 类,并当做属性注入到使用该类的其他类中,即可使用

②根据 JdbcDaoSupport 的源码分析,所以可以不用在 applicationContext.xml 文件中配置并注入模板类,而直接配置并注入数据库连接池即可

示例:

3.事务的管理

1)Spring的编程式事务管理(了解即可)

①配置平台事务管理器

 

②配置 TransactionTemplate 模板类

 

③在业务层注入事务的模板类 即 TransactionTemplate

 

 ④使用 TransactionTemplate 管理事务

 

2)Spring 的基于 AOP 的声明式事务管理

① XML 配置文件的方式(业务层的方法不需要任何修改)

> 配置平台事务管理器

> 先配置通知 注: tx:method 可以给方法设置一些数据库的属性,如:隔离级别、传播行为等 tx:method 的 name属性值可以带 * ,如 pay* 表示以 pay开头的方法

 

> 再配置 AOP 切面

 

② 使用注解的方式管理事务

> 配置平台事务管理器

> 开启事务的注解

 

> 在相应的 类上(表示此类中的所有方法都添加事务) 或 方法(只有此方法会添加事务)上添加 @Transactionl 注解

 

八、Spring 整合 SSH 三大框架

知识总结回顾:

1. Spring 整合 Struts2

1)方式一: Action 由 Struts2 创建并管理,需要依赖 struts2-spring-plugin-2.3.24.jar 这个 jar 包(不推荐使用)

① 在 struts.xml 文件中配置 Action

② 在 Action 中调用业务层的类,只要在 Spring 的配置文件中对业务层的类进行了配置,在 Action 中直接创建业务层的实例并提供 setter 方法,便可以直接调用业务层的方法。

2)方式二:Action 交由 Spring 创建并管理 (推荐使用)

① 在 Spring 的配置文件中配置 Action,必须配置成 多例的

② 重新配置 Struts.xml 配置文件中 Action 的配置,若 Action 交由 Spring 管理,其 action 节点的 class 属性为 Spring 配置文件中配置 Action 的 bean 节点的 id 属性值

③ 在 Spring 的配置文件中为 Action 注入业务层的引用属性

④ 使用:在 Action 类中定义相关业务层的引用属性,定义 setter 方法,使用即可

2.Spring 整合 Hibernate

1)方式一:带有 hibernate.cfg.xml 配置文件 (不推荐使用

① 持久层的类需要继承 HibernateDaoSupport,此类中具有 hibernateTemplate 引用属性,分析源码可知,此类还可以通过配置 SessionFactory获取 hibernateTemplate 对象。因为持久层的类继承了 HibernateDaoSupport,即获取了其 hibernateTemplate 引用属性和 SessionFactory引用属性,所以可以直接在 Spring 配置文件中为持久化类注入 SessionFactory

 

② 按 Hibernate 的步骤生成 hibernate.cfg.xml类名.hbm.xml 文件,并进行相应的配置,注:hibernate.cfg.xml 中不能配置绑定当前线程的操作,否则会报错!

③ 在 Spring 的配置文件中配置 LocalSessionFactoryBean,用来加载 hibernate.cfg.xml 文件和创建 SessionFactory 对象

 

④ 在 Spring 配置文件中配置平台事务管理器开启事务的注解,并在相应的业务层的类或方法上添加 @Transactionl 注解

 

2)方式二:不带有 hibernate.cfg.xml 配置文件 (推荐使用)

思考:没有 hibernate.cfg.xml 配置文件,即把 hibernate.cfg.xml 配置文件中的内容在 Spring 的配置文件中配置,所以,在方式一的基础上

① 在 Spring的配置文件中配置 c3p0 数据源

 

② 在 LocalSessionFactoryBean配置 数据库连接池,方言,可选值(是否打印 SQL,是否格式化 SQL,数据表的生成策略),引入映射的配置文件

 

3.Hibernate 模板类--- HibernateDAOSupport 的使用

1)HibernateDAOSupport 的 getHibernateTemplate() 方法同 Hibernate 的 Session 类似,可以对数据库进行增、删、改

 

2)查询一条记录,HQL查询所有记录,QBC 查询所有记录,分页查询

 

4. SSH 框架整合延迟加载问题的解决

1)使用 HIbernateTemplate.load() 方法,默认为延迟加载

2)异常:java.lang.ClassCastException: qi.spring.ssh1.domain.Customer_$$_javassist_0 cannot be cast to javassist.util.proxy.Proxy  是由包冲突造成的,删除低版本的即可

 

3)懒加载异常:org.hibernate.LazyInitializationException: could not initialize proxy - no Session 是由于延迟加载时 Session 已经关闭造成的

解决:

方案一:在 Customer.hbm.xml 中的 class 节点添加 lazy="false" 属性,关闭延迟加载,不推荐使用,此方案使程序性能降低

方案二:Spring解决延迟加载的问题在 web.xml 文件中配置一个过滤器,注:此过滤器一定要配置在 struts2 的核心过滤器之前推荐使用此方式

 

以上是关于深入浅出 Spring的主要内容,如果未能解决你的问题,请参考以下文章

「游戏引擎 浅入浅出」4.3 片段着色器

「游戏引擎 浅入浅出」4.3 片段着色器

Java线程池详解

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

Spring boot:thymeleaf 没有正确渲染片段