Spring学习记录

DI域属性的注入

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


第二种:使用byName方式注入

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


AOP

前置通知:

扫描二维码关注公众号,回复: 182418 查看本文章

定义接口

实现接口的目标对象


    

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

在配置文件中注册

后置通知

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

配置文件

环绕通知

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

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

配置文件


异常处理

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

ThrowsAdvice源代码


只能使用红框中的方法

复制粘贴后如下图

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


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

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

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


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

模拟使用顾问的环境

接口中有三个方法

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

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


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


使用ProxyFactoryBean会造成两个问题:

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

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

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

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

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

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

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

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



引入AspectJ

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

限定xml用aop的

基于注解的AOP编程

定义接口

创建实现类

切面类

配置文件



环绕通知

异常通知

最终通知

定义切入点

基于xml的AOP编程

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

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

配置切入点


后置通知

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包

建立实体

创建数据库表

定义业务层Service

先定义接口,在做实现

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

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


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

dao层实现

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

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

定义测试类

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


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

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

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

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


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

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

使用方式


当进行增删改时


当查询结果为字符串时

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

使用rowMapper

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



Spring的事务管理

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


假设有以下需求:

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

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

Account类


Stock类


account表

stock类


定义Service层

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

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

IAccountDao

AccountDaoImpl


IStockDao

StockDaoImpl

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

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

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

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

,即

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


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

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

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

2.使用注解式

在配置文件中添加


在实现类中

3.使用Aspectj管理实务


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

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



猜你喜欢

转载自blog.csdn.net/hcrw01/article/details/80186616