您的位置 首页 java

小实例理解Spring中的AOP—-面向切面编程

关于 面向切面编程 Spring AOP),是在java面试中经常提及的,只有在充分理解了,日常工作中才能得心应手。

如何理解AOP呢?首先我们要思考为什么要使用切面编程,如下图:

对于一个系统来说保存用户信息、权限分配的时候,我们会有数据库事务,保存要么同时成功,要么同时失败,用户信息、权限分配是面向对象设计的类对象,是横向的;数据库事

务是纵向的,像切面一样把他们切开。在编程中我们会发现:数据库的开闭,事务的管理是通用的,AOP可以抽取出来实现,简化我们的编程。

在Springboot中,javaBean是提供一个更强大的配置功能来增强JavaBean的功能,在java编程中,使用数据库时会写大量jdbc的try-catch代码,这个时候我们就能使用AOP编程将这些代码抽取出来,简化代码。

下面就用一个小实例初步理解面向切面编程(代码按照文末工程目录结构复制即可运行展示效果):

首先我们理解什么是动态代理模式:当你需要采访一名儿童的时候,首先你需要经过他的父母的同意,在一些问题上父母也许会替他回答,而对于另一些问题,也许父母觉得不太适合这个小孩会拒绝掉,这个时候小孩的父母就是他的代理(proxy)了。

动态代理的定义:生成一个占位,又称代理对象来代理目标对象,可以增强或者控制对孩子这个真实对象的访问。

1.约定编程,新建一个DinnerService接口

package com.springboot.chapter4.service;
/**
 * @Auther: 
 * @Date: 2019/3/17 09:56
 * @Description:
 */public interface DinnerService {
 public void eatDinner(String name);
}
 

再写一个DinnerService的实现类DinnerServiceImpl

package com.springboot.chapter4.service.impl;
import com.springboot.chapter4.service.DinnerService;
/**
 * 描述:
 *
 * @author 
 * @create 2019-03-17 9:58
 */public class DinnerServiceImpl implements DinnerService {
 @ Override 
 public void eatDinner(String name) {
 if(name == null || name.trim() == ""){
 throw new RuntimeException("parameter is null");
 }
 System.out.println("hello"+name);
 }
}
 

2.在JDK中提供了类Proxy的静态方法newProxyInstance作为代理对象,我们让代理类EatProxy通过实现InvocationHandler接口来实现代理功能,代码如下:

package com.springboot.chapter4.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * 描述:
 *
 * @author 
 * @create 2019-03-17 17:07
 */public class EatProxy implements InvocationHandler {
 // 引入目标对象:目的是吃晚餐
 private Object target;
 public static Object bind(Object target) {
 EatProxy eatProxy = new EatProxy();
 eatProxy.target = target;
 Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
 target.getClass().getInterfaces(),
 eatProxy);
 return proxy;
 }
 @Override
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 System.out.println("饭前洗手");
 Object obj = method.invoke(target, args);
 System.out.println("收拾饭菜");
 System.out.println("收拾餐具");
 return obj;
 }
}
 

其中重写的invoke方法作为代理处理逻辑来处理业务

3.再写一个主函数AopMain

package com.springboot.chapter4.main;
import com.springboot.chapter4.proxy.EatProxy;
import com.springboot.chapter4.service.DinnerService;
import com.springboot.chapter4.service.impl.DinnerServiceImpl;
/**
 * 描述:
 *
 * @author 
 * @create 2019-03-17 14:35
 */public class AopMain {
 public static void main(String[] args) {
 DinnerService dinnerService = new DinnerServiceImpl();
 DinnerService eatProxy = (DinnerService) EatProxy.bind(dinnerService);
 eatProxy.eatDinner("晚饭好吃");
 }
}
 

4.运行程序则可以看到”hello晚上吃饭“已经被调用,即我们第1步实现的接口代码已经被织入到约定的流程中。

项目工程截图如下:

文章来源:智云一二三科技

文章标题:小实例理解Spring中的AOP—-面向切面编程

文章地址:https://www.zhihuclub.com/192850.shtml

关于作者: 智云科技

热门文章

网站地图