1.事務的使用:
每次對數據庫操作我們都需要開啟事務,事務開啟后,我們就需要對數據庫進行一次或者多次操作,當操作完成后就需要提交事務。比如一個業務中多次操作數據庫,但是當某個方法出錯的時候,我們需要整體回滾,
所以我們把業務的操作綁定在一個事務中。)
2.手動實現aop管理事務
我們都知道,如果在業務流程代碼中增加事務的開啟與提交操作,那么我們在一個類中維護的將會是業務與事務的代碼。代碼少還可以,但是如果代碼量很大,維護起來將顯得臃腫復雜。那么我們能不能將業務與事務的代碼剝離開來,分開進行維護呢?
答案肯定是可行的。下面我們通過手動實現AOP代理。
AOP 面向切面的編程:
AOP可以實現“業務代碼”與“關注點代碼”分離,關注點代碼可以想象為事務的那部分代碼。
代碼示例:
IUserDao 接口對象
package com.murong.aop; //接口 public interface IUserDao { void save(); }
UserDao 目標對象
package com.murong.aop; import org.springframework.stereotype.Component; /** * 目標對象 */ @Component // 加入IOC容器 public class UserDao implements IUserDao { @Override public void save() { System.out.println("-----核心業務:保存!!!------"); } }
Aop 關注點代碼類
package com.murong.aop; import org.springframework.stereotype.Component; /** * 關注點代碼類 */ @Component // 加入IOC容器 public class Aop { // 重復執行的代碼 public void begin() { System.out.println("事務開啟"); } // 重復執行的代碼 public void end() { System.out.println("事務結束"); } }
ProxyFactory 代理工廠
package com.murong.aop; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 代理工廠 * */ public class ProxyFactory { public static Object newProxyInstance(final Object target,final Aop aop) { // 生成代理對象的方法 return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { aop.begin();// 關注點代碼 Object result = method.invoke(target, args);// 執行目標對象的方法 aop.end();// 關注點代碼 return result; } }); } }
applicationContext spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byType"> <!-- 開啟注解掃描 --> <context:component-scan base-package="com.murong.aop"></context:component-scan> <!-- 調用工廠方法,返回UserDao的代理對象 --> <bean id="userDao_proxy" class="com.murong.aop.ProxyFactory" factory-method="newProxyInstance"> <constructor-arg index="0" type="java.lang.Object" ref="userDao"></constructor-arg> <constructor-arg index="1" type="com.murong.aop.Aop" ref="aop"></constructor-arg> </bean> </beans>
App 測試類
package com.murong.aop; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { private ApplicationContext ac = new ClassPathXmlApplicationContext("com/murong/aop/applicationContext"); @Test public void test() { IUserDao dao = (IUserDao) ac.getBean("userDao_proxy"); dao.save(); } }
結果:
分析總結:
關注點代碼,就是指重復執行的代碼。
業務代碼與關注點代碼分離,好處?
-à 關注點代碼寫一次即可;
-à開發者只需要關注核心業務;
-à運行時期,執行核心業務代碼時候動態植入關注點代碼; 【代理】