关于上篇学习链接:Spring框架学习—Spring Framework上篇

目录:

  • 3.6 静态代理和动态代理
    • 3.6.1 静态代理
    • 3.6.2 动态代理
  • 3.7 AOP
  • 3.8 Spring整合Mybatis
  • 3.9 事物

3.6 静态代理和动态代理

3.6.1 静态代理

  • 生活中的代理(租客通过中介租到房东的房子)(例1)

角色分析:

项目框架:

Host.Java 相当于现实生活中的房东(准备出租房子的人)

上面的Rent为接口,表示出租操作

Proxy.java 相当于现实生活中的中介(房东将房子交给中介进行出租)

Client.Java相当于现实生活中的租客(准备租房子的人,租客通过中介租到房东的房子)

运行效果:

上面提到的四个角色,抽象角色对应Rent接口,真实角色对应房东,代理角色对应中介,客户角色对应租客。

代理模式的优缺点:

再来一个例子(例2):
项目结构:

UserService.Java 抽象角色

UserServiceImpl.Java 真实角色

Client.Java 客户角色

运行效果:

如果要给UserServiceImp里面每一个操作(增删改查)增加一个日志

像上面这种操作非常的麻烦,我们可以通过上面学到的代理来解决这个问题
首先先编写一个代理类(UserServiceProxy.Java),在代理类中添加日志业务,并在各个方法(增删改查)中实现日志

public class UserServiceProxy implements UserService {private UserService userService;public UserServiceProxy(UserService userService) {// TODO Auto-generated constructor stubthis.userService = userService;}@Overridepublic void add() {// TODO Auto-generated method stublog("add");userService.add();}@Overridepublic void delete() {// TODO Auto-generated method stublog("delete");userService.delete();}@Overridepublic void update() {// TODO Auto-generated method stublog("update");userService.update();}@Overridepublic void query() {// TODO Auto-generated method stublog("query");userService.query();}//打印日志方法public void log(String msg) {System.out.println("[Debug]使用了"+msg+"方法");}}

客户角色通过代理对象实现业务逻辑

运行效果:

上面的操作其实是一种横向开发(保持原有方法不变的情况下增加相应业务)

3.6.2 动态代理


通过动态代理实现例1:
项目结构:(Host.Java和Rent.Java和实例1无差别)

ProxyInvocationHandler.Java代理处理程序,用户生成代理,代理的相关操作

public class ProxyInvocationHandler implements InvocationHandler{private Rent rent;public void setRent(Rent rent) {this.rent = rent;}//生成得到代理类public Object getProxy() {return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces() , this);}// 处理代理实例,并返回结果@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// TODO Auto-generated method stub// 中介带租客看房子seeHouse();// 中介将房子出租给租客Object result=method.invoke(rent, args);//中介收取中介费fare();return result;}public void seeHouse() {System.out.println("中介看房子");}public void fare() {System.out.println("中介收费");}
}

client.Java 租客通过中介租房子

运行效果:

通过动态代理实现例2:
项目框架:

ProxyInvocationHandler.Java

public class ProxyInvocationHandler implements InvocationHandler{private UserService  userService;public void setRent(UserService userService) {this.userService = userService;}//生成得到代理类public Object getProxy() {return Proxy.newProxyInstance(this.getClass().getClassLoader(), userService.getClass().getInterfaces()   , this);}// 处理代理实例,并返回结果@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// TODO Auto-generated method stub//打印日志log(method.getName());//执行相应业务Object result=method.invoke(userService, args);return result;}//打印日志方法public void log(String msg) {System.out.println("[Debug]使用了"+msg+"方法");}}

Client.Java

运行效果:

从上面的实例2我们可以发现其实我们只是稍微修改了一下ProxyInvocationHandler.Java中接口对象,其实我们可以整理出一个模板如下图(将接口对象设置为Object对象):

具体代码如下:

public class ProxyInvocationHandler implements InvocationHandler{private Object   target;public void setTarget(Object target) {this.target = target;}//生成得到代理类public Object getProxy() {return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);}// 处理代理实例,并返回结果@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// TODO Auto-generated method stub//打印日志log(method.getName());//执行相应业务Object result=method.invoke(target, args);return result;}//打印日志方法public void log(String msg) {System.out.println("[Debug]使用了"+msg+"方法");}}

Client.Java中(需要使用的代理的类只需要给setTarget("接口“)传递一个接口对象即可)

运行效果一致:

动态代理的好处:

3.7 AOP

  • 什么是AOP?

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。[1]

简单解释:中文叫做面向切面编程,在不改变源码的情况下给程序动态添加功能的一种技术。

  • 相关概念
  • 实例1

环境搭建
项目结构:

maven:

<dependencies><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.3.9</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.9</version><scope>test</scope></dependency></dependencies>


service包:


log包:


resources包:
先导入aop的头文件

xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd

配置aop

测试类:

运行效果:

  • 另一种实现方式

新增一个diy包:

在包中增加一个DiyPointCut.Java类

修该配置(把原来胡aop配置注释了):

再次运行测试类:

  • 通过注解实现
    在DiyPointCut.Java类中,使用注解:

    开启注解支持(把前面的aop配置注释掉):

    再次运行测试类:
  • 环绕切入
    在DiyPointCut.Java类中添加一个around方法

    运行测试类(签名就是具体执行的哪一个方法):

3.8 Spring整合Mybatis

  • 整合前

项目架构:

Maven导入相关依赖:
在项目pom.xml中导入以下依赖

    <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.2</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.8.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.7.RELEASE</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.6</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>RELEASE</version><scope>compile</scope></dependency></dependencies>

Mybatis中资源导出失败解决之build配置

 <build><resources><resource><directory>src/main/java</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource></resources></build>

创建dao包:
创建UserMapper接口

创建UserMapper接口对应的mapper映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.UserMapper"><select id="selectUser" resultType="User">select * from user_test</select></mapper>

创建pojo包:
在包中创建User的实体类

在resources包中创建mybatis的配置文件(mybatis-config.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases><package name="pojo"/></typeAliases><!-- 对事务的管理和连接池的配置 --><environments default="development"><environment id="development"><transactionManager type="JDBC" /><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver" /><property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8" /><property name="username" value="root" /><property name="password" value="root" /></dataSource></environment></environments><mappers><mapper class="dao.UserMapper"></mapper></mappers>
</configuration>

创建测试类MyTest:

public class MyTest {@Testpublic void selectUser() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);List<User> userList = mapper.selectUser();for (User user: userList){System.out.println(user);}sqlSession.close();}
}

运行selectUser:

  • 整合后方式一(使用MyBatis-Spring)

什么是MyBatis-Spring?
MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。

相应版本对应:

导入MyBatis-Spring(在上面的项目中已经导入了该配置)

配置数据源替换mybaits的数据源:
创建spring-dao.xml

在spring-dao.xml中添加mybaits的数据源

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--配置数据源:数据源有非常多,可以使用第三方的,也可使使用Spring的--><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8"/><property name="username" value="root"/><property name="password" value="root"/></bean>
</beans>

在spring-dao.xml中配置SqlSessionFactory,关联MyBatis

    <!--配置SqlSessionFactory--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><!--关联Mybatis--><property name="configLocation" value="classpath:mybatis-config.xml"/><property name="mapperLocations" value="classpath:dao/*.xml"/></bean>

在配置文件中((mybatis-config.xml)只留下别名和相关配置即可(配置信息都移到上面去了)

在spring-dao.xml中注册sqlSessionTemplate,关联sqlSessionFactory;

   <!--注册sqlSessionTemplate , 关联sqlSessionFactory--><bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"><!--利用构造器注入--><constructor-arg index="0" ref="sqlSessionFactory"/></bean>

增加Dao接口的实现类;私有化sqlSessionTemplate

public class UserDaoImpl implements UserMapper {//sqlSession不用我们自己创建了,Spring来管理private SqlSessionTemplate sqlSession;public void setSqlSession(SqlSessionTemplate sqlSession) {this.sqlSession = sqlSession;}public List<User> selectUser() {UserMapper mapper = sqlSession.getMapper(UserMapper.class);return mapper.selectUser();}}

在spring-dao.xml中注册bean实现(初始化sqlSession)

  <bean id="userDao" class="dao.UserDaoImpl"><property name="sqlSession" ref="sqlSession"/></bean>

测试类中新增测试方法test2

    @Testpublic void test2(){ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");UserMapper mapper = (UserMapper) context.getBean("userDao");List<User> user = mapper.selectUser();System.out.println(user);}

运行test2

  • 整合方式二(通过继承SqlSessionDaoSupport,就无需再配置注册sqlSessionTemplate,因为SqlSessionDaoSupport提供了getSqlSession()可以直接获取SqlSession())

(备注:mybatis-spring1.2.3版才可以使用以下这种方式)

在spring-dao中把sqlSessionTemplate注释掉

创建一个UserDaorImpl2类,继承SqlSessionDaoSupport并且实现UserMapper接口

在applicationContext.xml配置中将bean进行修改(初始化sqlSessionFactory)

再次运行测试2:

3.9 事物

根据ACID原则一个操作执行要么成功,要么不成功,不存在一部分成功,一部分不成功,为了做到这一点,我们需要使用事务,事务分为编程式事务和声明式事务。

  • 编程式事务
    将事务管理代码嵌到业务方法中来控制事务的提交和回滚,这种方式有一个明显的缺点就是必须在每个事务操作业务逻辑中包含额外的事务管理代码。
  • 声明式事务
    将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理,但是这种方式需要Aop的支持,将事务管理作为横切关注点,通过aop方法模块化。

在spring-dao.xml配置文件中:
先导入事务(tx)和aop的头文件

       xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd

配置声明式事务

    <!--配置声明式事务--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean>

结合Aop实现事务的置入,先配置事务通知

    <!--配置事务通知--><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!--配置哪些方法使用什么样的事务,配置事务的传播特性--><tx:method name="add" propagation="REQUIRED"/><tx:method name="delete" propagation="REQUIRED"/><tx:method name="update" propagation="REQUIRED"/><tx:method name="search*" propagation="REQUIRED"/><tx:method name="get" read-only="true"/><tx:method name="*" propagation="REQUIRED"/></tx:attributes></tx:advice>

7种事务传播,默认REQUIRED

然后再配置事务的切入点

    <aop:config><aop:pointcut id="txPointcut" expression="execution(* dao.*.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/></aop:config>

在UserMapper接口中新增addUser(User user)和delUser(int id)二个方法

配置这二个方法的映射

在UserDaorImpl2类中

在映射文件中,我们故意把delUser的语句设置错误

测试类中,新增一个test3

运行情况

我们查看一下数据库中user_test表的数据,并没有增加(如果不使用事务的话,执行addUser是会成功的,就会增加数据)

Spring框架学习---Spring Framework下篇相关推荐

  1. Spring框架学习-Spring和IOC概述

    一:什么是Spring框架? spring是一个分层的javase/EEfull-stack(一站式)轻量级的java开源框架.是为了解决企业开发的复杂性而创建的.框架的主要优势是分层架构,Sprin ...

  2. Spring框架学习(二)

    Spring框架学习笔记---->AOP AOP概念 AOP:aspect oriented programing,面向切面编程. 将软件的各个模块,按照横向的角度进行观察,发现各个模块之间存在 ...

  3. Spring 框架(Spring Framework)使用详解

    概述 Spring 体系概述 Spring 是于2003年兴起的一个 full-stack 轻量级的 Java 开源框架,由 Rod Johnson 创建,使用 Spring 可以更快.更轻松.更安全 ...

  4. Spring框架学习笔记,超详细!!(4)

    Java小白开始学习Spring框架,一方面,跟着视频学习,并记录下学习笔记,方便以后复习回顾.另一方面,发布学习笔记来约束自己,学习路程还很遥远,继续加油坚持!!!希望能帮助到大家! 另外还有我的牛 ...

  5. Spring框架学习笔记(三)(AOP,事务管理)

    Spring框架学习笔记(三) 九.AOP 9.1 AOP的注解配置 (1) 新建计算器核心功能(模拟:不能在改动核心代码) (2) 建立一个普通的Java类写增强代码(面向切面编程),使用Sprin ...

  6. 框架学习—Spring

    框架学习-Spring(自我学习用) 1.概述 Spring是一个开源的轻量级开发框架,是为了解决企业应用程序的复杂性而创建的.以 IoC(Inverse of Control,控制反转)和 AOP( ...

  7. spring框架教程 Spring开发实例 spring mvc视频教程下载

    基于SpringMVC.MyBatis.FreeMarker架构实战CMS大型门户网站(自定义模板) spring框架教程 Spring开发实例 spring mvc视频教程下载地址: http:// ...

  8. 什么是spring框架?spring框架到底有什么用?spring框架到底做了些什么?

    什么是spring框架,spring框架究竟有什么用呢?我们可以用spring框架来做些什么呢?这是我今天要说的内容. 当然,百度spring框架会出现一大堆spring框架的介绍,以及IOC和AOP ...

  9. Spring框架学习路线

    文章目录 1.Spring 1.1.简介 1.2.优点 1.3.扩展 2.IOC理论 2.1.IOC的创建对象的方法 3.Spring配置 3.1.Bean配置 3.2.import 4.依赖注入 4 ...

  10. spring 框架学习(一)

    1.spring简介 Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成 ...

最新文章

  1. master page頁面如何用js來做輸入驗證
  2. 2018专业创业赛事服务平台
  3. PHP解决约瑟夫环问题
  4. vue 生产word_nodejs(officegen)+vue(axios)在客户端导出word文档
  5. centos7挂载nas存储_Geeki说丨浅谈几种存储添加主机映射方式
  6. 解题报告:51nod 加农炮
  7. 在下一个项目中不使用JavaDoc的5大原因
  8. Noip 2014酱油记+简要题解
  9. 使用phpStudyy运行tipask
  10. [转载] python中append函数的用法
  11. 液晶手写板原理拆解_汽车抬头显示HUD的拆解
  12. 实现审批系统_我市工程建设项目审批系统实现与 省监管平台数据互联互通
  13. centos6.5安装ansible和tower
  14. AI:人工智能的本质与未来
  15. *揭秘!阅读类APP如何实现自动阅读赚钱**
  16. 服务器上flash不显示动画,解决Firefox上网看不了Flash网页的问题
  17. 怎样可以促进睡眠质量?睡眠不好一定要知道这些方法
  18. 谐波减速器的结构简图及传动比说明
  19. 如何建立广泛、牢固的人脉?
  20. [转]黄金圣斗士处女座沙加读解

热门文章

  1. 在中国在行其道的智慧城市,为何折戟多伦多? | 凌云时刻
  2. 阿里云招聘----技术生态和技术战略专家
  3. 【情感识别】基于matlab GUI SVM语音情感识别(带面板)【含Matlab源码 876期】
  4. 【协同任务】基于matlab二阶一致性算法多无人机协同编队动态仿真【含Matlab源码 1740期】
  5. 毕设题目:Matlab数字信号处理
  6. 【图像融合】基于matlab小波变换全聚焦图像融合【含Matlab源码 1372期】
  7. 【数学建模】基于matlab GUI理发店排队模拟系统【含Matlab源码 1116期】
  8. 【图像融合】基于matlab curvelet变换图像融合【含Matlab源码 776期】
  9. 【图像配准】基于matlab GUI光流场模型医学图像配准【含Matlab源码 747期】
  10. 平安科技一轮等多久_科技正等着我们成长