您的位置: 首页 - 站长

wordpress 主题 简约新网站怎么做seo优化

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

wordpress 主题 简约,新网站怎么做seo优化,企业营销型网站团队,鲜花网站建设代理模式Proxy 代理模式 (Proxy)1) 静态代理1.a) 原理解析1.b) 使用场景1.c) 静态代理步骤总结 2) 动态代理2.a) 基于 JDK 的动态代理实现步骤2.b) 基于 CGLIB 的动态代理实现步骤2.c) Spring中aop的使用步骤 代理模式 (Proxy) 代理设计模式#xff08;Proxy Design PatternProxy Design Pattern是一种结构型设计模式它为其他对象提供一个代理以控制对这个对象的访问。代理模式可以用于实现懒加载、安全访问控制、日志记录等功能。 在设计模式中代理模式可以分为静态代理和动态代理。静态代理是指代理类在编译时就已经确定而动态代理是指代理类在运行时动态生成。

  1. 静态代理 1.a) 原理解析 在不改变原始类或叫被代理类代码的情况下通过引入代理类来给原始类附加功能。 1.b) 使用场景 1.缓存代理 缓存代理通常会在内部维护一个缓存数据结构如 HashMap 或者 LinkedHashMap用来存储已经处理过的请求及其结果。 假设有一个数据查询接口它从数据库或其他数据源中检索数据。在没有缓存代理的情况下每次查询都需要访问数据库这可能会导致较高的资源消耗和延迟。通过引入缓存代理我们可以将查询结果存储在内存中从而避免重复查询数据库。 public interface DataQuery {String query(String queryKey); }public class DatabaseDataQuery implements DataQuery {Overridepublic String query(String queryKey) {// 使用数据源从数据库查询数据很慢return result;} }创建一个缓存代理类它同样实现了 DataQuery 接口并在内部使用HashMap 作为缓存 public class DatabaseDataQueryProxy implements DataQuery {// 实现缓存需要数据结构private MapString, String cache new HashMap(256);// 你代理谁就要持有谁private DatabaseDataQuery dataQuery;public DatabaseDataQueryProxy() {// 1.屏蔽被代理对象this.dataQuery new DatabaseDataQuery();}Overridepublic String query(String queryKey) {// 2.对被代理对象的方法做增强// 2.1.查询缓存命中则返回String result cache.get(queryKey);if (result ! null) {System.out.println(命中缓存走缓存);return result;}// 2.2.未命中则查询数据库result dataQuery.query(queryKey);// 2.2.1.如果有结果需要将结果保存到缓存中再返回if (result ! null) {cache.put(queryKey, result);}System.out.println(未命中走持久层);return result;} }// 测试代码 Test void test() {DataQuery dataQuery new DatabaseDataQueryProxy();String value dataQuery.query(key1);System.out.println(value);value dataQuery.query(key1);System.out.println(value);value dataQuery.query(key2);System.out.println(value); }2.安全代理 用于控制对真实主题对象的访问。通过安全代理可以实现访问控制、权限验证等安全相关功能。 假设我们有一个敏感数据查询接口只有具有特定权限的用户才能访问 3.虚拟代理 在需要时延迟创建耗时或资源密集型对象。虚拟代理在初始访问时才创建实际对象之后将直接使用该对象。这可以避免在实际对象尚未使用的情况下就创建它从而节省资源。 以下是一个虚拟代理的应用示例 假设我们有一个大型图片类它从网络加载图像。由于图像可能非常大我们希望在需要显示时才加载它。为了实现这一点我们可以创建一个虚拟代理来代表大型图片类。 4.远程代理 用于访问位于不同地址空间的对象。远程代理可以为本地对象提供与远程对象相同的接口使得客户端可以透明地访问远程对象。通常远程代理需要处理网络通信、序列化和反序列化等细节。 1.c) 静态代理步骤总结 通过前四个案例我们也大致了解了静态代理的使用方式其大致流程如下 1.创建一个接口定义 代理类和被代理类 实现共同的接口2.创建被代理类实现这个接口并且在其中定义实现方法3.创建代理类也要实现这个接口同时在其中定义一个被代理类的对象作为成员变量4.在代理类中实现接口中的方法方法中调用 被代理类 中的对应方法5.通过创建代理对象并调用其方法方法增强 这样被代理类的方法就会被代理类所覆盖实现了对被代理类的增强或修改。
  2. 动态代理 静态代理需要手动编写代理类代理类与被代理类实现相同的接口或继承相同的父类对被代理对象进行包装。在程序运行前代理类的代码就已经生成并在程序运行时调用。静态代理的优点是简单易懂缺点是需要手动编写代理类代码复杂度较高且不易扩展。 动态代理是在程序运行时动态生成代理类无需手动编写代理类大大降低了代码的复杂度。动态代理一般使用 Java 提供的反射机制实现可以对任意实现了接口的类进行代理。动态代理的优点是灵活性高可以根据需要动态生成代理类缺点是性能相对较低由于使用反射机制在运行时会产生额外的开销。 2.a) 基于 JDK 的动态代理实现步骤 使用缓存代理的例子 public interface DataQuery {String query(String queryKey); }public class DatabaseDataQuery implements DataQuery {Overridepublic String query(String queryKey) {// 使用数据源从数据库查询数据很慢return result;} }创建一个代理类实现 InvocationHandler 接口实现invoke()方法并在其中定义一个被代理类的对象作为属性。 public class CacheInvocationHandler implements InvocationHandler {private MapString, String cache new HashMap(256);private DatabaseDataQuery databaseDataQuery;public CacheInvocationHandler() {this.databaseDataQuery new DatabaseDataQuery();}public CacheInvocationHandler(DatabaseDataQuery databaseDataQuery) {this.databaseDataQuery databaseDataQuery;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 1.判断是哪一个方法 (只对query方法做缓存)String result;if (query.equals(method.getName())) {// 2.查缓存// 2.1.命中直接返回result cache.get(args[0].toString());if (result ! null) {System.out.println(从缓存拿数据);return result;}// 2.2.未命中查询数据库 (需要代理实例)result (String) method.invoke(databaseDataQuery, args);// 3.查询到了进行缓存cache.put(args[0].toString(), result);return result;}// 当其他的方法被调用不希望被干预直接调用原生的方法return method.invoke(databaseDataQuery, args);} }主要业务逻辑 测试代码 Test void testJdkDynamicProxy() {// jdk提供的代理实现主要是使用Proxy类来实现// 参数1 classLoader被代理类的类加载器ClassLoader classLoader Thread.currentThread().getContextClassLoader();// 参数2 代理类需要实现的接口数组Class[] interfaces new Class[]{DataQuery.class};// 参数3 InvocationHandlerInvocationHandler invocationHandler new CacheInvocationHandler();DataQuery dataQuery (DataQuery) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);// 调用query方法时实际上是调用了invoke()方法String result dataQuery.query(key1);System.out.println(result);result dataQuery.query(key1);System.out.println(result);result dataQuery.query(key2);System.out.println(result);System.out.println(—————–);result dataQuery.queryAll();System.out.println(result); }2.b) 基于 CGLIB 的动态代理实现步骤 基于 CGLIB 的动态代理需要使用 net.sf.cglib.proxy.Enhancer 类和 net.sf.cglib.proxy.MethodInterceptor 接口。 1.创建一个被代理类定义需要被代理的方法 (以DatabaseDataQuery为例) public class DatabaseDataQuery {public String query(String queryKey) {// 使用数据源从数据库查询数据很慢System.out.println(正在从数据库中查询数据);return result;}public String queryAll() {System.out.println(正在从数据库中查询数据);return query All result;} }2.创建一个方法拦截器类实现 MethodInterceptor 接口并在其中定义一个被代理类的对象作为属性。 在 intercept 方法中我们可以对被代理对象的方法进行增强 public class CacheMethodInterceptor implements MethodInterceptor {private MapString, String cache new HashMap(256);private DatabaseDataQuery databaseDataQuery;public CacheMethodInterceptor() {this.databaseDataQuery new DatabaseDataQuery();}public CacheMethodInterceptor(DatabaseDataQuery databaseDataQuery) {this.databaseDataQuery databaseDataQuery;}Overridepublic Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {// 1.判断是哪一个方法String result;if (query.equals(method.getName())) {// 2.查询缓存命中则直接返回result cache.get(args[0].toString());if (result ! null) {System.out.println(从缓存中提取数据);return result;}// 3.未命中查询数据库result (String) method.invoke(databaseDataQuery, args);// 4.缓存到缓存中cache.put(args[0].toString(), result);return result;}return method.invoke(databaseDataQuery, args);} }3.在使用代理类时创建被代理类的对象和代理类的对象并使用 Enhancer.create 方法生成代理对象。 Test void testCgkibDynamicProxy() {// cglib通过enhancerEnhancer enhancer new Enhancer();// 1.设置父类enhancer.setSuperclass(DatabaseDataQuery.class);// 2.设置一个方法拦截器用来拦截方法enhancer.setCallback(new CacheMethodInterceptor());// 3.创建代理类DatabaseDataQuery databaseDataQuery (DatabaseDataQuery) enhancer.create();String value databaseDataQuery.query(key1);System.out.println(value);value databaseDataQuery.query(key1);System.out.println(value);value databaseDataQuery.query(key2);System.out.println(value); }2.c) Spring中aop的使用步骤 在 Spring 中AOP面向切面编程提供了一种有效的方式来对程序中的多个模块进行横切关注点的处理例如日志、事务、缓存、安全等。使用 Spring AOP可以在程序运行时动态地将代码织入到目标对象中从而实现对目标对象的增强。 Spring AOP 的使用步骤如下 1.引入 AOP 相关依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactIdversion2.3.9.RELEASE/version /dependency2.在Main中开启自动代理EnableAspectJAutoProxy SpringBootApplication EnableAspectJAutoProxy public class Main {public static void main(String[] args) {SpringApplication.run(Main.class, args);} }3.定义接口和实现类并将具体实现注入容器 (以DatabaseDataQuery为例) // 接口 public interface DataQuery {String query(String queryKey); }// 实现类 Component public class DatabaseDataQuery implements DataQuery {Overridepublic String query(String queryKey) {// 使用数据源从数据库查询数据很慢System.out.println(正在从数据库中查询数据);return result;} }4.定义切面类对方法做增强 Pointcut() 对某包下的某个类的某个方法做增强.. 代表任意方法Around() 定义增强 Component Aspect public class CacheAspectj {private static MapString,String cache new ConcurrentHashMap(256);Pointcut(execution(* com.dcy.structural.proxy.dynamicProxy.aop.impl.DatabaseDataQuery.query(..)))public void pointcut() {}Around(pointcut())public String around(ProceedingJoinPoint joinPoint) {// 1.查询缓存Object[] args joinPoint.getArgs();String key args[0].toString();// 1.1.命中则返回String result cache.get(key);if (result ! null) {System.out.println(数据从缓存中提取);return result;}// 2.未命中查询数据库实际上是调用被代理bean的方法try {result joinPoint.proceed().toString();// 如果查询有结果进行缓存cache.put(key, result);} catch (Throwable e) {throw new RuntimeException(e);}return result;} }5.测试用例 SpringBootTest public class AopTest {Resourceprivate DataQuery dataQuery;Testvoid testSpringAop() {String result dataQuery.query(key1);System.out.println(result);result dataQuery.query(key1);System.out.println(result);result dataQuery.query(key2);System.out.println(result);}}