010_AOPXml方式开发
1. 什么是AOP?
2. Spring底層的AOP實現原理
2.1. AOP應用場景
2.2. Spring動態代理
2.2.1. JDK動態代理: 只能對實現了接口的類產生代理。
2.2.2. CGLIB動態代理: 對沒有實現接口的類產生代理。CGLIB(Code Generation Library)是一個開源的, 強大的, 高性能, 高質量的Code生成類庫。Spring引入了它。
3. AOP簡介
3.1. AOP思想最早是由AOP聯盟組織提出的。Spring是使用這種思想的最好的框架。
3.2. AspectJ是一個面向切面的框架, 它擴展了Java語言。
3.3. Spring早期的AOP是自己實現的, 但是十分繁瑣。后來Spring引入了AspectJ進行AOP開發。
4. AOP術語
5. Spring中通知類型
5.1. 前置通知: 在目標方法執行之前進行操作。
5.2. 后置通知: 在目標方法執行之后進行操作。
5.3. 環繞通知: 在目標方法執行之前和之后進行操作。
5.4. 異常拋出通知: 在程序出現異常的時候進行操作。
5.5. 最終通知: 無論代理是否有異常, 總會執行。
6. 切入點表達式語法
6.1. 基于execution的函數完成的。
6.2. [訪問修飾符] 返回值類型 包名.類名.方法名(參數), 訪問修飾符可以省略不寫。
6.3. public void com.lywgames.dao.impl.UserDaoImpl.insert(..), 參數使用.., 表示任意參數。
6.4. * com.lywgames.dao.impl.UserDaoImpl.insert(..), 返回值使用*, 表示任意返回值類型。
6.5. * com..UserDaoImpl.insert(..), 包路徑可以使用..做省略, 但是必須有開頭。
6.6. * com.lywgames.dao.impl.*.*(..), 該包下的所有類的所有方法。
7. 引入aop的約束
8. 切入點配置
9. 通知配置
10. JDK動態代理例子
10.1. 新建一個名為JdkProxy的Java項目
10.2. 創建UserDao.java接口
package com.lywgames.dao;public interface UserDao {void insert();void select();void update();void delete(); }10.3. 創建UserDao.java接口的實現類UserDaoImpl.java
package com.lywgames.dao.impl;import com.lywgames.dao.UserDao;public class UserDaoImpl implements UserDao {@Overridepublic void insert() {System.out.println("插入User對象。");}@Overridepublic void select() {System.out.println("查詢User對象。");}@Overridepublic void update() {System.out.println("更新User對象。");}@Overridepublic void delete() {System.out.println("刪除User對象。");}}10.4. 創建JDKProxy.java代理類
package com.lywgames.proxy;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import com.lywgames.dao.UserDao;public class JDKProxy implements InvocationHandler{private UserDao userDao;public JDKProxy(UserDao userDao) {this.userDao = userDao;}public UserDao createProxy() {return (UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if("select".equals(method.getName())) {System.out.println("查詢User對象前, 對其進行校驗。");return method.invoke(userDao, args);}return method.invoke(userDao, args);}}10.5. 創建Test.java測試類
package com.lywgames;import com.lywgames.dao.UserDao; import com.lywgames.dao.impl.UserDaoImpl; import com.lywgames.proxy.JDKProxy;public class Test {public static void main(String[] args) {UserDao userDao = new UserDaoImpl();JDKProxy jdkProxy = new JDKProxy(userDao);UserDao proxy = jdkProxy.createProxy();proxy.insert();proxy.select();proxy.update();proxy.delete();} }10.6. 運行項目
11. CGLIB動態代理例子
11.1. 新建一個名為CglibProxy的Java項目, 拷入spring-core.java, 她有CGLIB代碼
11.2. 創建UserDaoImpl.java類
package com.lywgames.dao.impl;public class UserDaoImpl {public void insert() {System.out.println("插入User對象。");}public void select() {System.out.println("查詢User對象。");}public void update() {System.out.println("更新User對象。");}public void delete() {System.out.println("刪除User對象。");}}11.3. 創建CglibProxy.java代理類
package com.lywgames.proxy;import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import com.lywgames.dao.impl.UserDaoImpl;public class CglibProxy implements MethodInterceptor {private UserDaoImpl userDaoImpl;public CglibProxy(UserDaoImpl userDaoImpl) {this.userDaoImpl = userDaoImpl;}// 使用cglib產生代理public UserDaoImpl createProxy() {// 創建cglib的核心類Enhancer enhancer = new Enhancer();// 設置父類enhancer.setSuperclass(userDaoImpl.getClass());// 設置回調enhancer.setCallback(this);// 返回增強對象return (UserDaoImpl)enhancer.create();}@Overridepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {if("insert".equals(method.getName())) {System.out.println("插入User對象前, 對其進行校驗。");return methodProxy.invokeSuper(proxy, args);}return methodProxy.invokeSuper(proxy, args);}}11.4. 創建Test.java測試類
package com.lywgames;import com.lywgames.dao.impl.UserDaoImpl; import com.lywgames.proxy.CglibProxy;public class Test {public static void main(String[] args) {UserDaoImpl userDaoImpl = new UserDaoImpl();CglibProxy cglibProxy = new CglibProxy(userDaoImpl);UserDaoImpl proxy = cglibProxy.createProxy();proxy.insert();proxy.select();proxy.update();proxy.delete();} }11.5. 運行項目
12. AOP使用XML配置例子
12.1. 新建一個名為AOPXml的Java項目
12.2. 創建UserDao.java接口
package com.lywgames.dao;public interface UserDao {public void insert();public void select();public void update();public int delete(); }12.3. 創建UserDao.java接口的實現類UserDaoImpl.java
package com.lywgames.dao.impl;import com.lywgames.dao.UserDao;public class UserDaoImpl implements UserDao {public void insert() {System.out.println("插入數據");}public void select() {System.out.println("查詢數據");}public void update() {System.out.println("更新數據");throw new RuntimeException();}public int delete() {System.out.println("刪除數據");return 1;}}12.4. 創建AspectJAop.java切面類
package com.lywgames.aop;import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint;public class AspectJAop {public void beforeInsertCheck(JoinPoint jp) {System.out.println("檢測插入數據, " + jp);}public void afterDelete(int result) {System.out.println("刪除后返回值: " + result);}public Object arround(ProceedingJoinPoint joinPoint) {try {System.out.println("查詢前鼓鼓掌。");Object obj = joinPoint.proceed();System.out.println("查詢后鼓鼓掌。");return obj;} catch (Throwable e) {e.printStackTrace();}return null;}public void updateException(Throwable ex) {System.out.println("更新發生了異常:" + ex.toString());}public void myFinally() {System.out.println("更新方法發生了異常, 最終通知一樣會執行完成。");} }12.5. 創建AopAction.java測試類
package com.lywgames.action;import org.springframework.context.support.ClassPathXmlApplicationContext; import com.lywgames.dao.UserDao;public class AopAction {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");UserDao userDao = context.getBean(UserDao.class);userDao.insert();userDao.delete();userDao.select();userDao.update();context.close();} }12.6. 在src目錄下添加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"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="userDao" class="com.lywgames.dao.impl.UserDaoImpl"></bean><bean id="aspectJAop" class="com.lywgames.aop.AspectJAop"></bean><!-- 通過aop的配置完成對目標類產生代理 --><aop:config><!-- 表達式配置哪些類的哪些方法需要進行增強 --><aop:pointcut expression="execution(* com..UserDaoImpl.insert(..))" id="pointinsert" /><aop:pointcut expression="execution(* com.lywgames.dao.impl.UserDaoImpl.delete(..))" id="pointdelete"/><aop:pointcut expression="execution(* com.lywgames.dao.impl.UserDaoImpl.select(..))" id="pointselect"/><aop:pointcut expression="execution(* com.lywgames.dao.impl.UserDaoImpl.update(..))" id="pointupdate"/> <!-- 配置切面 --><aop:aspect ref="aspectJAop"><!-- 引用切面類 --><!-- 前置通知 --><aop:before method="beforeInsertCheck" pointcut-ref="pointinsert" /><!-- 后置通知 --><aop:after-returning method="afterDelete" pointcut-ref="pointdelete" returning="result"/><!-- 環繞通知 --><aop:around method="arround" pointcut-ref="pointselect"/><!-- 異常通知 --><aop:after-throwing method="updateException" pointcut-ref="pointupdate" throwing="ex" /> <!-- 最終通知 --><aop:after method="myFinally" pointcut-ref="pointupdate"/></aop:aspect></aop:config></beans>12.7. 運行項目
總結
以上是生活随笔為你收集整理的010_AOPXml方式开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 009_IOC注解开发
- 下一篇: 011_AOP注解开发