Spring学习记录

DI域属性的注入

给引用属性注入时有三种方式,第一种:使用byType方式注入


Spring学习记录

第二种:使用byName方式注入

Spring学习记录

使用byName方式注入的第二种:使用@Resource标签并制定name属性

Spring学习记录


AOP

前置通知:

定义接口

Spring学习记录

实现接口的目标对象

Spring学习记录

    

新建自己的前置通知类来实现MethodBeforeAdvice接口,其中method是目标对象的方法,args是参数,target是目标对象

Spring学习记录

在配置文件中注册

Spring学习记录

后置通知

新建类实现AfterReturningAdvice接口,其中比前置通知多了一个属性 returnValue,该属性是目标方法的返回值,可以使用,但是无法修改该返回值。

Spring学习记录

配置文件

Spring学习记录

环绕通知

新建类实现接口MyMethodInterceptor,有两个同名的接口,应该实现aop联盟的那一个

Spring学习记录

Spring学习记录

环绕通知有返回值,所以可以修改目标方法的返回值,比如目标方法返回小写的abcdefghijk,可以在环绕方法中把它变成大写的

配置文件

Spring学习记录


异常处理

新建类实现ThrowsAdvice接口,这个接口有点特殊,实现它后不强制实现任何方法,需要查看其源代码

Spring学习记录

ThrowsAdvice源代码

Spring学习记录

只能使用红框中的方法

复制粘贴后如下图

Spring学习记录

afterThrowing(想要处理的异常 ex),触发想要处理的异常后会执行方法体内的逻辑


目标对象有接口时,自动使用JDK动态代理

目标对象没有接口时,自动使用的是CGLIB动态代理

也可以自己指定使用cglib进行代理

Spring学习记录

使用通知时,类中的所有方法都被作为了切入点。因为有的时候不需要全部方法都作为切入点,所以引入顾问。

模拟使用顾问的环境

接口中有三个方法

Spring学习记录

需求:当执行doFirst时给一个后置通知,执行其他方法时不触发通知

使用名称匹配方法切入点顾问

Spring学习记录

使用正则表达式匹配方法切入点顾问

Spring学习记录

使用ProxyFactoryBean会造成两个问题:

1.若存在多个目标对象,就需要使用多次ProxyFactoryBean来创建多个代理对象,这会使配置文件变的臃肿

2.用户真正想要调用的是目标对象,而真正可以调用的确实代理对象,这不符合正常的逻辑

所以引入了自动代理生成器

Spring学习记录

注册自动代理生成器后,不需要再手动创建代理工厂Bean了,自动代理生成器的底层实现是使用了Bean后处理器。

默认自动代理(DefaultAdvisorAutoProxyCreator)存在着三个问题:

1.不能选择目标对象(它把所有的顾问分别给所有的目标对象都绑定上)

2.不能选择切面类型,切面只能是advisor(顾问)

使用BeanNameAutoProxyCreator(名称自动代理生成器)可以解决以上问题

Spring学习记录


引入AspectJ

环境搭建:添加四个包 1. aop 2. aop 联盟 3. aspects 4. aspectj.weaver

限定xml用aop的

基于注解的AOP编程

定义接口

Spring学习记录

创建实现类

Spring学习记录

切面类

Spring学习记录

配置文件

Spring学习记录


环绕通知

Spring学习记录

异常通知

Spring学习记录

最终通知

Spring学习记录

定义切入点

Spring学习记录

基于xml的AOP编程

 把刚才用的切面类的注解都删除

Spring学习记录

配置文件中的aspectj自动代理也删除掉,配置aop config

Spring学习记录

配置切入点

Spring学习记录

后置通知

Spring学习记录

Spring学习记录

Spring的JDBC模板

环境搭建

导入jar包

jdbc:spring-jdbc-4.2.4.RELEASE.jar

事务: spring-tx-4.2.4.RELEASE.jar

连接数据库驱动:mysql-connector-java-5.1.31.jar 

数据库连接池:

com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar

  com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar

  com.springsource.org.apache.commons.pool-1.5.3.jar

还有一些spring基础jar包

建立实体

Spring学习记录

创建数据库表

Spring学习记录

定义业务层Service

先定义接口,在做实现

Spring学习记录

实现时,肯定会需要调用dao层

先假设有dao层用着,并且给dao写一个set方法,给后面用容器注入做准备

Spring学习记录

然后定义dao接口,因为我们只是模拟一下环境,没有具体的业务逻辑,所以dao层的方法和service层是一样的,更改了一些方法名,add ---- insert   remove  --- delete   find  --- select  modify ----- update

Spring学习记录

dao层实现

Spring学习记录

实现dao层的增删改查,正式引入jdbc模板,让实现类继承JdbcDaoSupport,然后使用getJdbcTemplate()得到JdbcDaoSupport的属性jdbcTemplate,用jdbcTemplate对数据库进行增删改查的操作

增删改都是用update方法实现的

Spring学习记录

定义测试类

因为增删改查都需要使用ApplicationContext对象,所以把它设为成员属性,并且设置before,就不需要写在每一个test方法中了

Spring学习记录


很显然在测试方法中需要获取到IServiceStudent的实现对象,所以需要编写配置文件

在配置文件中写StudentServiceImpl时需要设值注入dao,所以还要配置dao,配置dao时,需要配置dao继承的

JdbcDaoSupport类中的属性JdbcTemplate,配置JdbcTemplate又需要配置DataSource属性,配置完成后如下图

Spring学习记录

其它种类的数据源配置如下

Spring学习记录

把数据库连接四要素存放到properties文件中

Spring学习记录

在配置文件中配置该文件后,才能使用,使用格式: ${jdbc.****}

Spring学习记录

使用方式

Spring学习记录

当进行增删改时

Spring学习记录

当查询结果为字符串时

Spring学习记录

当查询结果为对象时,因为对象有很多属性,所以要使用一个实现RowMapper接口的类对那些属性进行封装,

Spring学习记录

使用rowMapper

Spring学习记录

可以不手动配置jdbcTemplate,直接把数据源注入给dao时,会自动创建出jdbcTemplate

Spring学习记录


Spring的事务管理

事务传播拿回家吃饺子的例子来比喻


假设有以下需求:

在进行股票交易时,付钱后得到股票,钱减少,股票增多,如果出现异常要发生回滚。

模拟一个环境,建立实体类以及数据库表

Account类

Spring学习记录

Stock类

Spring学习记录

account表

Spring学习记录

stock类

Spring学习记录

定义Service层

Spring学习记录

编写其实现类,当编写其实现类时,肯定要用到dao层,先假设有dao层,并且有我们要用的方法,如下

Spring学习记录

然后补齐这个实现类所需要的接口,实现类

IAccountDao

Spring学习记录

AccountDaoImpl

Spring学习记录

IStockDao

Spring学习记录

StockDaoImpl

Spring学习记录

当然这些dao都是通过注入获取到的,而且dao层实现也需要注入数据源,所以编写主配置文件如下

Spring学习记录

因为需求中要求要抛出异常,所以我们手动制造一个异常抛出去

直接抛出异常时,会报错,因为无法通过编译

Spring学习记录

我们可以加一个判断,骗过编译器就可以通过编译了

Spring学习记录,即

此时执行测试方法test02后会发现,钱少了,股票没加,这肯定是不可以接受的,所以我们要使用事务

Spring学习记录

有三种方式可以实现事务管理

1.使用事务代理管理实务

Spring学习记录

这种方法存在的问题是,每一个目标类都得有一个代理对象,冗余太大,而且调用时要调用代理对象,不符合常规逻辑

2.使用注解式

在配置文件中添加

Spring学习记录

在实现类中

Spring学习记录

3.使用Aspectj管理实务


根据不同的情况选择不同的sql语句时,下面的写法可以用,但是效率稍微低

Spring学习记录

下面的写法,先给定一个默认值,再根据不同的情况进行选择不同的sql语句,效率会有所提升

Spring学习记录