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

移动端网站制作谷歌浏览器怎么下载

移动端网站制作,谷歌浏览器怎么下载,福建微网站建设公司推荐,如何做下载网站学习设计模式不光要学习设计模式的思想,还要去深入理解,为什么要用这个设计模式。 如何深入理解?读优秀的框架代码,看别人代码,了解它们的使用场景。 - - - 博主老师(感谢他) 本文先介绍了代理模…

学习设计模式不光要学习设计模式的思想,还要去深入理解,为什么要用这个设计模式。
如何深入理解?读优秀的框架代码,看别人代码,了解它们的使用场景。 - - - 博主老师(感谢他)

本文先介绍了代理模式的概念及简单实现。简单聊了下为什么要使用代理模式,并介绍了代理模式在spring中的使用

代理模式

  • 1、概念
  • 2、实现
    • 2.1 静态代理
    • 2.2 动态代理
  • 3、为什么使用代理类模式
  • 4、Spring中的代理模式

1、概念

定义:为其他对象提供一种代理以控制对这个对象的访问。

在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

2、实现

考虑这么个例子:
只有管理员才能看销售数据

2.1 静态代理

静态代理在代理类中持有关键业务实例的引用

用户接口

public interface IUser {void visitData();}

用户类

public class User implements IUser {private String type;public User(String type) {this.type = type;}@Overridepublic void visitData() {System.out.println("看到了数据...");}public String getType() {return type;}
}

用户代理

public class UserProxy implements IUser {private User user;public UserProxy(User user) {this.user = user;}@Overridepublic void visitData() {if (user.getType().equals("admin")) {user.visitData();} else {System.out.println("没有权限");}}
}

测试

public class Test {public static void main(String[] args) {User admin = new User("admin");User normal = new User("normal");UserProxy adminProxy = new UserProxy(admin);adminProxy.visitData();UserProxy normalProxy = new UserProxy(normal);normalProxy.visitData();}
}

输出

看到了数据...
没有权限

2.2 动态代理

代理目标可以在运行时动态注入,代理的关键业务随着代理目标实例的不同而不同。常见的技术实现手段有:JDK提供的Proxy类+InvocationHandler接口,CGLIB,Javassist库等。我们使用jdk的InvocationHandler实现。

动态代理可以基于jdk的InvocationHandler实现

public class DynamicProxy implements InvocationHandler {private Object obj;public DynamicProxy(Object obj) {this.obj = obj;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = method.invoke(obj, args);return result;}
}

测试类

public class Test2 {public static void main(String[] args) {IUser user = new User("admin");DynamicProxy proxy = new DynamicProxy(user);ClassLoader loader = proxy.getClass().getClassLoader();// 1、ClassLoader 方法需要动态生成一个类 需要一个ClassLoader来加载该类  // 2、Class[] interfaces 需要代理的对象的Class数组 // 3、InvocationHandler 调用处理器IUser userProxy = (IUser) Proxy.newProxyInstance(loader, new Class[] {IUser.class}, proxy);userProxy.visitData();}
}

输出

看到了数据...

3、为什么使用代理类模式

在上面的例子中,权限过滤为什么要让代理类去做?而不是直接在user的visitData方法里做判断呢?
因为面向对象的六大原则中有个叫:单一职责原则

  1. 代理模式可以在不破坏原有业务处理边界的前提下,增加额外的定制需求。
  2. 假如要调用的对象是一个远程的对象,需要跨网络访问。如果让你直接coding去调用,你需要处理网络连接、处理打包、解包等等非常复杂的步骤,所以为了简化客户端的处理,我们使用代理模式,在客户端建立一个远程对象的代理,客户端就象调用本地对象一样调用该代理,再由代理去跟实际对象联系。

4、Spring中的代理模式

我们都知道spring aop是基于动态代理实现的。

通过@EnableAspectJAutoProxy可以开启aop

package org.springframework.context.annotation;@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {// aop的实现方式,ture:CGLIB, false:jdk的InvocationHandler, 默认是falseboolean proxyTargetClass() default false;// 暴露方式,默认为false, 为true的时候,可以解决内部调用不能使用的场景// 假设类有方法doSomething1()和doSomething2(),doSomething1()方法内部调用doSomething2()。在调用doSomething1()的时候,默认情况下aop只会对doSomething1()做增强,不会对doSomething2()做增强(尽管doSomething1内部调用了doSomething2(),且单独调用doSomething2()的是,2也能被增强)。  // 为true的时候,可以实现内部调用,不过在doSomething1()中调用doSomething2()的代码也要改下:XX proxy=(xx) AopContext.currentProxy();proxy.doSomething2();boolean exposeProxy() default false;
}

@Import:将bean加载到spring容器
源码里:@Import({AspectJAutoProxyRegistrar.class}) 就是将AspectJAutoProxyRegistrar这个bean加载到容器中。

// ImportBeanDefinitionRegistrar的类只能通过@import加载
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {// 将AspectJAnnotationAutoProxyCreator装载到spring容器。  AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);...}}

将AspectJAnnotationAutoProxyCreator装载到spring容器。
AnnotationAwareAspectJAutoProxyCreator实现了(父类实现)BeanPostProcessor接口,接口的postProcessAfterInitialization方法会在bean初始化完成后被调用。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupportimplements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {@Overridepublic Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {if (bean != null) {Object cacheKey = getCacheKey(bean.getClass(), beanName);if (this.earlyProxyReferences.remove(cacheKey) != bean) {// 对bean进行包装,返回代理类return wrapIfNecessary(bean, beanName, cacheKey);}}return bean;}protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {...// Create proxy if we have advice.Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);if (specificInterceptors != DO_NOT_PROXY) {this.advisedBeans.put(cacheKey, Boolean.TRUE);Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}
}

上面的代码可以看到,如果有切面,bean会在初始化完只后,被包装成代理对象。

createProxy方法

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,@Nullable Object[] specificInterceptors, TargetSource targetSource) {if (this.beanFactory instanceof ConfigurableListableBeanFactory) {AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);}// 1.创建proxyFactory, 代理的工厂类ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.copyFrom(this);if (!proxyFactory.isProxyTargetClass()) {if (shouldProxyTargetClass(beanClass, beanName)) {proxyFactory.setProxyTargetClass(true);}else {evaluateProxyInterfaces(beanClass, proxyFactory);}}// 2.将当前bean适合的advice,重新封装下,封装为Advisor类,然后添加到ProxyFactory中Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);proxyFactory.addAdvisors(advisors);proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);proxyFactory.setFrozen(this.freezeProxy);if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);}return proxyFactory.getProxy(getProxyClassLoader());
}

getProxy根据不同的情况,生产不同的代理对象。我们看使用JDK自带的代理方式的实现

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {@Overridepublic Object getProxy(@Nullable ClassLoader classLoader) {if (logger.isTraceEnabled()) {logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());}Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);}
}

JDK动态代理模式,真正的方法执行在invoke()方法里,继续看这个类的invoke方法

	/*** Implementation of {@code InvocationHandler.invoke}.* <p>Callers will see exactly the exception thrown by the target,* unless a hook method throws an exception.*/@Override@Nullablepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {...try {// 获取当前bean被拦截方法链表List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);// 如果为空,则直接调用target的methodif (chain.isEmpty()) {Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);}// 不为空,则逐一调用chain中的每一个拦截方法的proceedelse {MethodInvocation invocation =new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);retVal = invocation.proceed();}...return retVal;}...}

参考:
https://www.cnblogs.com/silverLee/archive/2010/02/05/1664577.html

https://blog.csdn.net/JinXYan/article/details/89302126

http://www.lbrq.cn/news/2747143.html

相关文章:

  • 连云港网站建设案例公司推广
  • 澳门建设银行官方网站网站seo站外优化
  • 晋中建设集团有限公司网站手机如何制作网页链接
  • 电商网站设计的原则百度网讯科技客服人工电话
  • 东莞建网站服务免费建自己的网址
  • 手机系统网站有哪些百度网页怎么制作
  • 仿做国外产品网站出路电商代运营公司排名
  • 网站里面内外链接如何做网络推广都有哪些方式
  • 资兴做网站公司网页制作的基本步骤
  • css是在网站开发的应用大型营销型网站制作
  • 河东做网站郑州网站排名推广
  • 成都企业网站建设哪家专业优化师是做什么的
  • 网站建设需要域名吗?国际新闻今天
  • mysql数据库做网站网站推广系统
  • 做哪一类网站能赚钱seo扣费系统
  • 深圳我的网站广州线下培训机构停课
  • 网站设计与网页制作在线企业信息查询
  • 武汉网站设计公司排名新站快速收录
  • 游戏开发有前途吗seo培训机构排名
  • 成都电商app开发seo同行网站
  • 网站制作创业磁力狗在线
  • 医疗机械网站怎么做哪个合肥seo好
  • 做网站银川快推达seo
  • 高端网站建设服务商外贸网站推广怎么做
  • 日本真人做爰无遮挡视频免费网站网站推广策划报告
  • 深圳网站建公司天津疫情最新消息
  • 辽宁手机版建站系统开发网站的推广方式
  • 动态网站开发 用什么模板语言企业管理
  • 沈阳专业网站制作设计淘宝的关键词排名怎么查
  • 做自己的博客网站网销怎么销售的
  • C语言(12)——进阶函数
  • 麒麟V10静默安装Oracle11g:lsnrctl、tnsping等文件大小为0的解决方案
  • JVM学习笔记-----StringTable
  • Mac(四)自定义按键工具 Hammerspoon 的安装和使用
  • 各种读取csv文件的工具性能比较
  • 计算机存储器分类和层次结构详解