当前位置: 首页 > news >正文

网站的设计与制作阅读第2版企业营销型网站策划务

网站的设计与制作阅读第2版,企业营销型网站策划务,岳阳seo优化,wordpress怎么部署到虚拟linux服务器目录 一、AOP的概念 二、AOP的底层实现原理 2.1 JDK的动态代理 2.1.1 invocationhandler接口 2.1.2 代理对象和原始类实现相同的接口 interfaces 2.1.3 类加载器ClassLoador 2.1.4 编码实现 2.2 Cglib动态代理 2.2.1 Cglib动态代理编码实现 三、AOP如何通过原始对象的id获取到代…

目录

一、AOP的概念

二、AOP的底层实现原理

2.1 JDK的动态代理

2.1.1 invocationhandler接口

2.1.2 代理对象和原始类实现相同的接口 interfaces

2.1.3 类加载器ClassLoador

2.1.4 编码实现

2.2 Cglib动态代理

2.2.1 Cglib动态代理编码实现

三、AOP如何通过原始对象的id获取到代理对象

3.1 BeanPostProcessor

3.2 编码实现


一、AOP的概念

AOP(Aspect Oriented Programing)即面向切面编程,以切面为基本单位的程序开发,通过切面间的彼此协同,相互调用,完成程序的构建。这里的 切面 = 切入点 + 额外功能,所以我们常说的AOP也就等同于Spring中的动态代理开发!那么什么是切面呢?当在不同的ServiceImpl中,需要添加同一个额外功能的时候,这几个类的方法中所添加的相同额外功能就会由点构成面,所以就将这个称为是切面

二、AOP的底层实现原理

2.1 JDK的动态代理

由于这里是探索AOP底层的实现原理,所以我们这里先摒弃Spring框架。首先我们需要了解代理创建的三个要素(1.原始对象 2.额外功能 3.代理对象和原始对象实现相同的接口),有了这三个要素之后就能创建出一个代理对象,接下来画图分析

首先将这个原始对象创建出来,在添加额外功能和实现相同的接口的时,使用JDK的Proxy类中的newProxyInstance(动态字节码技术)方法来完成。要了解一个类中方法的具体使用,就需要了解这个类中参数的具体含义

2.1.1 invocationhandler接口

这里的invocationhandler接口就是完成额外功能的,实现这个接口时要实现这个invoke方法,提到这个invoke方法是不是就联想到了Spring中的拦截器MethodInterceptor中的invoke方法?其实MethodInterceptor中的invoke方法就是对这一系列的操作进行了封装

invocationHandler接口中的invoke方法有三个参数,其中proxy忽略掉

method:额外功能所增加给的原始方法

args:原始方法的参数

method调用其invoke方法使得原始方法运行起来,那么我们想要添加额外功的就只需要添加在method.invoke的前后即可。这样额外功能的添加就完成了

2.1.2 代理对象和原始类实现相同的接口 interfaces

这里的参数interfaces是获取到原始对象实现的那个接口。通过获取类文件在获取接口来实现

2.1.3 类加载器ClassLoador

在一般创建对象的过程都是通过类加载器将对应的字节码文件加载到JVM,同时类加载器创建类的class对象,进而创建出这个类的对象。其中CL表示类加载器,同时获取这个类加载器也不需要我们担心,每一个类的.class文件都会自动分配一个

但是在创建动态代理类的时候是没有源文件的,它是通过动态字节码技术(Proxy.newProxyInstance)去创建字节码的。由于动态代理技术是直接将字节码文件写入JVM中的,并没有这个类加载器,但是我们又需要使用类加载器去帮我们创建代理类对象,那这个时候怎么办呢?借一个嘛!所以这就是参数中需要一个类加载器的原因

2.1.4 编码实现

创建接口

public interface UserService {void register();boolean login();
}

原始方法实现这个类 

public class UserServiceImpl implements UserService{@Overridepublic void register() {System.out.println("register核心功能正在执行");}@Overridepublic boolean login() {System.out.println("login核心功能正在执行");return false;}
}

添加额外功能 

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class TestJDKProxy {public static void main(String[] args) {// 创建原始对象UserService userService = new UserServiceImpl();// 以下是JDK动态代理创建// 实现InvocationHandler接口,为了方便演示采取内部类的方式InvocationHandler handler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 原始方法运行Object ret = method.invoke(userService,args);// 在原始方法后面添加额外功能System.out.println("aop底层实现----额外功能添加在原始功能后面----log");return ret;}};// TestJDKProxy.class.getClassLoader()借用一个类加载器,借谁的无所谓// userService.getClass().getInterfaces() 拿到原始类的接口// 使用相同的接口接收代理类UserService userServiceProxy =(UserService) Proxy.newProxyInstance(TestJDKProxy.class.getClassLoader(),userService.getClass().getInterfaces(),handler);// 调用核心方法 观察额外功能是否添加完成userServiceProxy.login();userServiceProxy.register();}
}

至此,JDK的动态代理原理就已经全部分析完了

2.2 Cglib动态代理

首先在开始Cglib动态代理之前,我们在回顾以下JDK动态代理的过程。JDK动态代理类通过与原始类实现同一个接口从而完成额外功能的添加。但是在现实开发的过程中有没有一种可能这个原始类没有实现任何的接口,那这个时候该怎么办呢?这个时候就需要使用Cglib动态代理来完成了

Cglib是怎么完成这个代理类的实现的呢?Cglib是采取了继承的方式来完成代理类的实现的

由于这里的Cglib动态代理的实现与JDK动态代理的实现是高度一致的,这里就只介绍二者的区别了,而不再介绍相同点了

2.2.1 Cglib动态代理编码实现

Cglib动态代理的实现中是通过Enhancer类中的一系列方法来完成的,通过setClassLoder方法去设置类加载器,通过setSuperClass方法设置父类对象,通过setCallback方法设置额外功能,当然这个额外功能也要去实现接口,这里的接口是MethodInterceptor(这个并不是Spring提供的那个接口,而是Cglib包中的接口),最后通过create方法创建动态代理对象

public class UserServiceImpl{public void register() {System.out.println("register核心功能正在执行");}public boolean login() {System.out.println("login核心功能正在执行");return false;}
}
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class TestCglib {public static void main(String[] args) {// 创建原始对象UserServiceImpl userService = new UserServiceImpl();// 以下是Cglib创建动态代理对象Enhancer enhancer = new Enhancer();// TestCglib.class.getClassLoader() 借用的类加载器enhancer.setClassLoader(TestCglib.class.getClassLoader());// userService.getClass() 获取到的父类对象enhancer.setSuperclass(userService.getClass());MethodInterceptor interceptor = new MethodInterceptor() {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {// 添加额外功能System.out.println("Cglib底层实现------额外功能添加在方法执行前---log");// 原始方法执行Object ret = method.invoke(userService, args);return ret;}};// 设置额外功能enhancer.setCallback(interceptor);// 创建动态代理对象UserServiceImpl userServiceCglib = (UserServiceImpl) enhancer.create();userServiceCglib.register();userServiceCglib.login();}
}

 

三、AOP如何通过原始对象的id获取到代理对象

3.1 BeanPostProcessor

在Spring中提供了一个接口BeanPostProcessor,这个接口是用来加工Spring通过配置文件创建的对象的。通过实现接口中的postProcessorAfterInitialization方法,就可以实现通过原始对象的id值获取到代理对象了(也就是通过这个接口对原始类进行再加工)

3.2 编码实现

首先在Spring的配置文件中创建UserServiceImpl的对象,这里是实现的接口,所以动态代理应该使用JDK动态代理的方式

public class UserServiceImpl implements UserService{@Overridepublic void register() {System.out.println("register核心功能正在执行");}@Overridepublic boolean login() {System.out.println("login核心功能正在执行");return false;}
}
<bean id="userService" class="com.gl.demo.proxy.UserServiceImpl"/>

创建好对象以后,创建一个类实现BeanPostProcessor接口为原始类进行加工,进而将代理类返回给用户

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class BeanPostProcessorTest implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// 在这个方法中对需要添加额外功能的类进行加工// 这里采取JDK动态代理的方式进行加工// BeanPostProcessorTest.class.getClassLoader() 借用的类加载器// bean.getClass().getInterfaces()获取原始类的接口// 实现InvocationHandler接口添加额外功能InvocationHandler handler = new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object ret = method.invoke(bean, args);System.out.println("spring底层实现动态代理----额外功能添加在原始方法后---log");return ret;}};// 将代理类返回给用户而不是原始类return Proxy.newProxyInstance(BeanPostProcessorTest.class.getClassLoader(),bean.getClass().getInterfaces(),handler);}
}

最后将加工的好的代理对象配置在Spring的配置文件中

<bean id="proxyBeanProcessor" class="com.gl.demo.proxy.BeanPostProcessorTest"/>

这时候,用户通过原始类的id值拿到的是代理类而不是原始类了,进而完成了动态代理的过程

public void test4() {ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config2.xml");UserService userService = (UserService) ctx.getBean("userService");userService.register();userService.login();
}

至此,AOP底层原理就已经全部分析完毕了!以上的工作Spring其实都给我们封装好了,在日后的开发过程中直接使用就可以了,不用这么麻烦!

http://www.yayakq.cn/news/638051/

相关文章:

  • 网站开发的体会施工企业上市公司
  • 制作网站软件哪个好书店网站模板
  • 设计比例网站微信朋友圈推广
  • 创建网站公司 徐州网站 内容 制作
  • 创建简易个人网站wordpress保存图片插件
  • 清远住房和城乡建设部网站手机小程序制作
  • 手机上怎么做网站创业数据库和网站开发
  • 网站建设用免费素材广西营销型网站建设公司
  • 建网站价格网做网站如何避免侵权
  • 瑞安专业网站建设百度门店推广
  • 购物网站分为几个模块精神文明网站建设内容
  • 成都网站建设上云长沙第三方网站建设公司
  • 高端网站制作费用德州网页设计师培训
  • destoon 网站后台dw可以做网站吗
  • 在线编辑图片的网站有哪些枣庄网页制作公司
  • 各大网站网络推广的收费济南旅游团购网站建设
  • 网站建设丨找王科杰上词快江西南昌网站建设哪家好
  • 河南郑州创建网站公司店铺装修网站
  • 网站建设有利于做监控的有哪些网站
  • 装潢公司网站模块后台管理网站开发
  • 新泰网站开发中国排名前十的广告公司
  • 交易类网站建设费用百度录取线我的wordpress
  • nas云存储做视频网站动态交互图表制作
  • 可以用来做简单的网络验证的网站推进网站建设工作计划
  • 私人找人做网站手机免费图片制作软件
  • 建筑网名windows优化软件
  • 新网站怎么做谷歌推广呢柳州市建设工程质量安全监督管理处网站
  • 网站开发成本如何账务处理房在线房产中介管理系统
  • 旅游订票网站开发黑龙江省瑞驰建设集团网站
  • 站长友情链接指数分布的期望和方差