javascript
Spring(四)——AOP、Spring实现AOP、Spring整合Mybatis、Spring中的事务管理
文章目錄
- 1. 什么是AOP
- 2. 使用Spring實現AOP
- 2.1 使用Spring的API 接口實現
- 2.2 自定義實現
- 2.3 使用注解實現
- 3. 整合MyBatis
- 3.1 MyBatis-Spring簡述
- 3.2 知識基礎
- 3.3 整合mybatis的測試
- 4. 事務
- 4.1 回顧事務
- 4.2 spring中的事務管理
- 4.3 事務的測試
1. 什么是AOP
AOP(Aspect Oriented Programming)意為:面向切面編程,通過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。AOP是OOP的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生范型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。
不影響原來的業務情況下,動態新增功能。
2. 使用Spring實現AOP
2.1 使用Spring的API 接口實現
主要SpringAPI接口實現
(1)創建一個新maven項目,導入pom依賴
pom.xml文件:
(2)創建一個接口,創建一個接口的實現類
UserService接口:
UserServiceImpl 接口實現類:
package com.zz.service.impl;import com.zz.service.UserService;public class UserServiceImpl implements UserService {public void add() {System.out.println("增加用戶");}public void delete() {System.out.println("刪除用戶");}public void update() {System.out.println("更新用戶");}public void search() {System.out.println("查詢用戶");} }(3)創建兩個增加類(前置,后置)
Log 日志增強類(前置):
LogAfter日志增強類(后置):
package com.zz.config; //日志增強類 后置 import org.springframework.aop.AfterReturningAdvice; import java.lang.reflect.Method;public class LogAfter implements AfterReturningAdvice {public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {System.out.println(target.getClass().getName()+"的"+method.getName()+"方法返回了"+returnValue);} }(4)在applicationContext.xml文件中配置增強類實現增強:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--注冊bean--><bean id="userService" class="com.zz.service.impl.UserServiceImpl"/><bean id="log" class="com.zz.config.Log"/><bean id="afterlog" class="com.zz.config.LogAfter"/><!--aop的配置方式一:配置增強類--><aop:config><!--切入點,哪些方法需要增強expression 表達式是類名的全稱,確定到實現類中的方法--><aop:pointcut id="pc-userservice" expression="execution(* com.zz.service.impl.UserServiceImpl.*(..))"/><!--環繞 即將UserServiceImpl中的所有方法做前置和后置增強--><aop:advisor advice-ref="log" pointcut-ref="pc-userservice"/><aop:advisor advice-ref="afterlog" pointcut-ref="pc-userservice"/></aop:config></beans>(5)Test 測試類:
import com.zz.service.UserService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;//客戶端 public class MyTest {@Testpublic void test1(){ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = (UserService) context.getBean("userService");userService.add();} }測試結果:
2.2 自定義實現
主要是切面定義,切面就是一個類
(1)創建一個自定義類 DiyPointCut:
(2)在applicationContext.xml文件中配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--注冊bean--><bean id="diy" class="com.zz.config.DiyPointCut"/><!--aop的配置方式二:配置增切面--><aop:config><aop:aspect ref="diy"><aop:pointcut id="pc-userservice" expression="execution(* com.zz.service.impl.UserServiceImpl.*(..))"/><aop:before method="before" pointcut-ref="pc-userservice"/><aop:after method="after" pointcut-ref="pc-userservice"/></aop:aspect></aop:config> </beans>(3)Test 測試類:
代碼與上面相同
測試結果:
2.3 使用注解實現
(1)創建一個類 AnnotationPointCut
package com.zz.config;import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before;//注解實現增強,切面原理 @Aspect public class AnnotationPointCut {@Before("execution(* com.zz.service.impl.UserServiceImpl.*(..))")public void before(){System.out.println("=====方法執行前=====");}@After("execution(* com.zz.service.impl.UserServiceImpl.*(..))")public void after(){System.out.println("=====方法執行后=====");} }(2)在applicationContext.xml文件中配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--注冊bean--><bean id="annotationPointCut" class="com.zz.config.AnnotationPointCut"/><!--aop的配置方式三:使用注解實現增強類--><!--讓spring識別注解,一定要添加--><aop:aspectj-autoproxy/> </beans>(3)Test 測試類:
代碼與上面相同
測試結果:
3. 整合MyBatis
參考學習網站:http://mybatis.org/spring/zh/index.html
3.1 MyBatis-Spring簡述
MyBatis-Spring 會幫助你將 MyBatis 代碼無縫地整合到 Spring 中。它將允許 MyBatis 參與到 Spring 的事務管理之中,創建映射器 mapper 和 SqlSession 并注入到 bean 中,以及將 Mybatis 的異常轉換為 Spring 的 DataAccessException。最終,可以做到應用代碼不依賴于 MyBatis,Spring 或 MyBatis-Spring。
3.2 知識基礎
在開始使用 MyBatis-Spring 之前,你需要先熟悉 Spring 和 MyBatis 這兩個框架和有關它們的術語。這很重要——因為本手冊中不會提供二者的基本內容,安裝和配置教程。
MyBatis-Spring 需要以下版本:配套
3.3 整合mybatis的測試
目錄:
(1)在pom.xml文件中導入所有依賴
(2)實體類User:
對應MySQL數據庫里的user表
(3)UserMapper接口:
package com.zz.mapper;import com.zz.pojo.User;import java.util.List;public interface UserMapper {public List<User> getUserList();}(4)接口的實現類UserMapperImpl:
package com.zz.mapper.impl;import com.zz.mapper.UserMapper; import com.zz.pojo.User; import org.mybatis.spring.SqlSessionTemplate;import java.util.List;public class UserMapperImpl implements UserMapper {//注入sqlSessionprivate SqlSessionTemplate sqlSession ;public void setSqlSession(SqlSessionTemplate sqlSession) {this.sqlSession=sqlSession;}public List<User> getUserList(){UserMapper mapper = sqlSession.getMapper(UserMapper.class);return mapper.getUserList();} }(5)接口的配置文件UserMapper.xml:
<?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="com.zz.mapper.UserMapper"><select id="getUserList" resultType="User">select * from user</select> </mapper>(6)配置文件applicationContext.xml:
<?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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!--1.數據源整合--><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? useUnicode=true&characterEncoding=utf8&useSSL=false"/><property name="username" value="root"/><property name="password" value="123456"/></bean><!--2. 注入sqlSessionFactory--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><!--掃描包--><property name="typeAliasesPackage" value="com.zz.pojo"/><property name="mapperLocations" value="classpath:com/zz/mapper/xml/*.xml"/></bean><!--3.創建sqlSession--><bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"><constructor-arg index="0" ref="sqlSessionFactory"/></bean><!--4. 將sqlSession放入Bean中--><bean id="userMapperImpl" class="com.zz.mapper.impl.UserMapperImpl"><property name="sqlSession" ref="sqlSession"/></bean> </beans>(7)測試類MyTest:
import com.zz.mapper.UserMapper; import com.zz.pojo.User; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest {@Testpublic void test1(){ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");UserMapper userMapperImpl = (UserMapper) context.getBean("userMapperImpl");for (User user : userMapperImpl.getUserList()) {System.out.println(user);}} }測試結果:
4. 事務
4.1 回顧事務
- 把一組業務當成一個業務來做;要么都成功,要么都失敗!
- 事務在項目開發中,十分的重要,涉及到數據的一致性問題,不能馬虎!
- 確保完整性和一致性
事務ACID原則:
- 原子性
- 一致性
- 隔離性
- 多個業務可能操作同一個資源,防止數據損壞
- 持久性
- 事務一旦提交,無論系統發生什么問題,結果都不會再被影響,被持久化的寫到存儲器中!
4.2 spring中的事務管理
- 聲明式事務 : AOP
- 編程式事務: 需要再代碼中,進行事務的管理
思考:
為什么需要事務?
- 如果不配置事務,可能存在數據提交不一致的情況下;
- 如果我們不在SPRING中去配置聲明式事務,我們就需要在代碼中手動配置事務!
- 事務在項目的開發中十分重要,設計到數據的一致性和完整性問題,不容馬虎!
4.3 事務的測試
(1)在UserMapper接口中加入兩個方法
//添加事務int addUser(User user);//刪除用戶int deleteUser(int id);(2)在接口的配置文件UserMapper.xml中編寫對應的sql語句
注意:故意將刪除語句寫錯,寫為deletes
(3)在接口的實現類UserMapperImpl中重寫方法
package com.zz.mapper.impl;import com.zz.mapper.UserMapper; import com.zz.pojo.User; import org.mybatis.spring.SqlSessionTemplate;import java.util.List;public class UserMapperImpl implements UserMapper {//注入sqlSessionprivate SqlSessionTemplate sqlSession ;public void setSqlSession(SqlSessionTemplate sqlSession) {this.sqlSession=sqlSession;}public List<User> getUserList(){UserMapper mapper = sqlSession.getMapper(UserMapper.class);//錯誤操作User user = new User(4,"小麗","123456");mapper.addUser(user);mapper.deleteUser(3); //sql存在錯誤return mapper.getUserList();}public int addUser(User user) {UserMapper mapper = sqlSession.getMapper(UserMapper.class);return mapper.addUser(user);}public int deleteUser(int id) {UserMapper mapper = sqlSession.getMapper(UserMapper.class);return mapper.deleteUser(id);} }(4)其他代碼與上面均不變,進行測試,并分析測試結果
發現控制臺結果確實報錯,但是點開MySQL,刷新user表,發現添加4號用戶成功,刪除3號用戶失敗。
這在實際的應用中,顯然是不滿足要求的,我們必須加入事務,使它符合事務的原則,讓一組操作保證同時成功或同時失敗!
(5)在applicationContext.xml中添加事務配置
導入事務tx和aop的命名空間:
還添加如下配置:
(6)再次測試(此時還未改正sql語句)
發現控制臺結果報錯,再點開MySQL,刷新user表,發現添加用戶和刪除用戶均失敗。
(7)最后將刪除用戶的sql語句改正正確,再次測試
發現添加用戶和刪除用戶均正確,控制臺和數據庫user列表顯示完全一致!
總結
以上是生活随笔為你收集整理的Spring(四)——AOP、Spring实现AOP、Spring整合Mybatis、Spring中的事务管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring(三)——HelloSpri
- 下一篇: SpringMVC(一)——入门案例