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

网站建设z亿玛酷1订制中山做百度网站的公司名称

网站建设z亿玛酷1订制,中山做百度网站的公司名称,北京4网站建设,最好看免费观看视频大全结构性模式#xff1a;适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式 适配器模式 适配器模式#xff08;Adapter Pattern#xff09; 充当两个不兼容接口之间的桥梁#xff0c;属于结构型设计模式。目的是将一个类的接口转换为另一个接口适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式 适配器模式 适配器模式Adapter Pattern 充当两个不兼容接口之间的桥梁属于结构型设计模式。目的是将一个类的接口转换为另一个接口使得原本不兼容的类可以协同工作用户调用适配器转化出来的目标方法适配器再调用被适配的方法这样用户就看不到被配置者感觉只是和目标方法交互达到了解耦适配器模式主要分为三类是根据被适配者的类是怎么给到适配器来命名的 类适配器模式适配器继承被适配的类对象适配器模式适配器持有一个被适配者的对象接口适配器模式适配器将被适配者作为接口实现 使用场景 需要使用现有类但其接口不符合系统需求。希望创建一个可复用的类与多个不相关的类包括未来可能引入的类一起工作这些类可能没有统一的接口。通过接口转换将一个类集成到另一个类系中。 实现方式 继承或依赖推荐使用依赖关系而不是继承以保持灵活性。 适配器模式包含以下几个主要角色 目标接口Target定义客户需要的接口。适配者类Adaptee定义一个已经存在的接口这个接口需要适配。适配器类Adapter实现目标接口并通过组合或继承的方式调用适配者类中的方法从而实现目标接口。 类适配器模式 优点 促进了类之间的协同工作即使它们没有直接的关联。提高了类的复用性。增加了类的透明度。提供了良好的灵活性可以重写被适配的类中的方法。 缺点 过度使用适配器可能导致系统结构混乱难以理解和维护。在Java中由于只能继承一个类因此只能适配一个类且目标类必须是抽象的。而且被适配的类的所有方法都会暴露出来增加了使用成本 /*** 被适配的类*/ public class AdaptationTest {public Integer test(int a, int b) {return a b;} }/*** 目标接口*/ public interface ITargetInterTest {// 客户需要的接口Double work(int a, int b);}/*** 适配器*/ public class Adaptation extends AdaptationTest implements ITargetInterTest {Overridepublic Double work(int a, int b) {// 对被适配者进行处理达到用户的需求return (test(a, b) * 1.2) 100;} }/*** 用户*/ public class UseTest {public static void main(String[] args) {Adaptation adaptation new Adaptation();Double work adaptation.work(10, 20);System.out.println(work);}}对象适配器模式 对象适配器 对象适配器思路和类适配器模式相同只不过是不在继承被适配的类而是持有这个类的实例来解决兼容性问题根据合成复用原则再系统中尽量使用关联关系来替代继承关系 /*** 被适配的类*/ public class AdaptationTest {public Integer test(int a, int b) {return a b;} }/*** 目标接口*/ public interface ITargetInterTest {// 客户需要的接口Double work(int a, int b);}/*** 对象适配器持有被适配的对象*/ public class AdaptationPloy implements ITargetInterTest {private AdaptationTest adaptationTest;public AdaptationPloy(AdaptationTest adaptationTest) {this.adaptationTest adaptationTest;}Overridepublic Double work(int a, int b) {// 对被适配者进行处理达到用户的需求return (adaptationTest.test(a, b) * 1.2) 100;} }/*** 用户*/ public class UseTest {public static void main(String[] args) {ITargetInterTest a1 new AdaptationPloy(new AdaptationTest());System.out.println(a1.work(30,10));}}接口适配器模式 接口适配器模式 当不需要全部实现接口提供的方法时可以先设计一个抽象类实现接口并为接口中的方法提供默认实现空方法那么该抽象类的子类就可以有选择的覆盖父类的某些方法来实现需求 /*** 有很多方法的接口*/ public interface Inter1 {void a();void b();void c(); }/*** 默认实现*/ public abstract class AbsClass implements Inter1{Overridepublic void a() {System.out.println(默认的实现a);}Overridepublic void b() {System.out.println(默认的实现b);}Overridepublic void c() {System.out.println(默认的实现c);} }/*** 因为抽象类已经默认实现了接口方法所以只实现需要使用的方法即可*/ public class Test {public static void main(String[] args) {Inter1 inter new AbsClass() {public void a() {System.out.println(子类自行实现想要用到的方法);}};inter.a();inter.b();inter.c();} } 桥接模式 桥接模式 桥接Bridge模式属于结构型设计模式基于类的最小设计原则将抽象和实现放在不同的类层次中通过提供抽象化和实现化之间的桥接结构来实现二者的解耦。有一个桥接的接口使得实体类的功能独立于接口实现类这两种类型的类可被结构化改变而互不影响。桥接模式的目的是将抽象与实现分离使它们可以独立地变化该模式通过将一个对象的抽象部分与它的实现部分分离使它们可以独立地改变。通过组合而不是继承的方式将抽象和实现的部分连接起来。 使用场景 当系统可能从多个角度进行分类且每个角度都可能独立变化时桥接模式是合适的。 以下是桥接模式的几个关键角色 抽象类Abstraction定义抽象接口通常包含对实现接口的引用聚合关系扩展抽象Refined Abstraction对抽象的扩展可以是抽象类的子类或具体实现类。行为实现类Implementor定义实现接口提供基本操作的接口。行为实现的具体实现类Concrete Implementor实现实现接口的具体类。 行为实现类及其子类定义了基本操作和具体实现 /*** 行为实现类Implementor定义实现接口提供基本操作的接口*/ public interface Implementor {String watchMovie();String game(); }/*** 行为实现的具体实现类实现实现接口的具体类。*/ public class GameImplementor implements Implementor {Overridepublic String watchMovie() {return 游戏本看电影;}Overridepublic String game() {return 游戏本打游戏;} }/*** 行为实现的具体实现类实现实现接口的具体类。*/ public class lightImplementor implements Implementor {Overridepublic String watchMovie() {return 轻薄本看电影;}Overridepublic String game() {return 轻薄本打游戏;} }抽象类及其实现 抽象类充当了一个桥梁的作用抽象类的子类调用和抽象类的方法抽象类再去调用行为实现的具体实现类 的方法 /*** 抽象类Abstraction定义抽象接口*/ public abstract class Shape {Implementor implementor;public Shape(Implementor implementor) {this.implementor implementor;}String watchMovie(){return implementor.watchMovie();}String game(){return implementor.game();}}/*** 扩展抽象对抽象的扩展可以是抽象类的子类或具体实现类。*/ public class ShapeAsus extends Shape {public ShapeAsus(Implementor drawCircular) {super(drawCircular);}OverrideString watchMovie() {return 华硕super.watchMovie();}OverrideString game() {return 华硕super.game();} }/*** 扩展抽象对抽象的扩展可以是抽象类的子类或具体实现类。*/ public class ShapeMSI extends Shape{public ShapeMSI(Implementor implementor) {super(implementor);}OverrideString watchMovie() {return 微星super.watchMovie();}OverrideString game() {return 微星super.game();} } 测试类 public class Client {public static void main(String[] args) {Shape shape new ShapeMSI(new lightImplementor());System.out.println(shape.watchMovie();shape.game());Shape shape1 new ShapeMSI(new GameImplementor());System.out.println(shape1.watchMovie();shape1.game());Shape shape2 new ShapeAsus(new GameImplementor());System.out.println(shape2.watchMovie();shape2.game());Shape shape3 new ShapeAsus(new lightImplementor());System.out.println(shape3.watchMovie();shape3.game());} } 优点 抽象与实现分离提高了系统的灵活性和可维护性。扩展能力强可以独立地扩展抽象和实现。实现细节透明用户不需要了解实现细节。 缺点 理解与设计难度桥接模式增加了系统的理解与设计难度。聚合关联要求开发者在抽象层进行设计与编程。 装饰器模式 装饰器模式 动态的将新功能附加到对象上再对象功能扩展方面比继承更加有弹性也体现了开闭原则ocp装饰器模式允许向一个现有的对象添加新的功能同时又不改变其结构。属于结构型模式装饰器模式提供了一种灵活的替代继承方式来扩展功能 关键代码 Component接口定义了可以被装饰的对象的标准快递的物品ConcreteComponent类实现Component接口的具体类。Decorator抽象类实现Component接口并包含一个Component接口的引用。ConcreteDecorator类扩展Decorator类添加额外的功能。给快递的物品增加包装例如泡沫塑料、纸板等 装饰器模式包含以下几个核心角色 抽象组件Component定义了原始对象和装饰器对象的公共接口或抽象类可以是具体组件类的父类或接口。具体组件Concrete Component是被装饰的原始对象它定义了需要添加新功能的对象。抽象装饰器Decorator继承自抽象组件它包含了一个抽象组件对象并定义了与抽象组件相同的接口同时可以通过组合方式持有其他装饰器对象。具体装饰器Concrete Decorator实现了抽象装饰器的接口负责向抽象组件添加新的功能。具体装饰器通常会在调用原始对象的方法之前或之后执行自己的操作。 /*** 可以被装饰的对象*/ public interface Component {void pack(); }/*** 扩展Decorator类添加额外的功能*/ public class ClothesComponent implements Component {Overridepublic void pack() {System.out.println(打包一件衣服);} }/*** 实现Component接口的具体类*/ public class PorcelainComponent implements Component {Overridepublic void pack() {System.out.println(打包一个瓷器);} } /*** Decorator抽象类实现Component接口并包含一个Component接口的引用*/ public abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component component;}public abstract void extend();}/*** 扩展Decorator类添加额外的功能*/ public class ConcreteDecorator1 extends Decorator {public ConcreteDecorator1(Component component) {super(component);}Overridepublic void pack() {component.pack();extend();}public void extend() {System.out.println(需要填充塑料泡沫并且固定在木箱中寄出);}}/*** 扩展Decorator类添加额外的功能*/ public class ConcreteDecorator2 extends Decorator {public ConcreteDecorator2(Component component) {super(component);}Overridepublic void pack() {component.pack();extend();}public void extend() {System.out.println(不需要填充物使用塑料袋寄出即可);}} 测试类 public class Client {public static void main(String[] args) {Decorator decorator new ConcreteDecorator1(new PorcelainComponent());decorator.pack();System.out.println(----------);Decorator decorator1 new ConcreteDecorator2(new ClothesComponent());decorator1.pack();}} 结果如下 优点 低耦合装饰类和被装饰类可以独立变化互不影响。灵活性可以动态地添加或撤销功能。替代继承提供了一种继承之外的扩展对象功能的方式。 缺点 复杂性多层装饰可能导致系统复杂性增加。 使用建议 在需要动态扩展功能时考虑使用装饰器模式。保持装饰者和具体组件的接口一致以确保灵活性。装饰器模式虽然可以替代继承但应谨慎使用避免过度装饰导致系统复杂度过高。 组合模式 组合模式Composite Pattern 又叫部分整体模式是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象用来表示部分以及整体层次。这种类型的设计模式属于结构型模式它创建了对象组的树形结构。 这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。 组合模式的核心角色包括 组件Component: 定义了组合中所有对象的通用接口可以是抽象类或接口。它声明了用于访问和管理子组件的方法包括添加、删除、获取子组件等。 叶子节点Leaf: 表示组合中的叶子节点对象叶子节点没有子节点。它实现了组件接口的方法但通常不包含子组件。 复合节点Composite: 表示组合中的复合对象复合节点可以包含子节点可以是叶子节点也可以是其他复合节点。它实现了组件接口的方法包括管理子组件的方法。 客户端Client: 通过组件接口与组合结构进行交互客户端不需要区分叶子节点和复合节点可以一致地对待整体和部分。 关键代码 Component接口定义了所有对象必须实现的操作。Leaf类实现Component接口代表树中的叶子节点。Composite类也实现Component接口并包含其他Component对象的集合。 使用场景 当要处理的对象可以生成一颗树型结构如文件系统或组织结构。而我们要对树上的节点和叶子进行操作能够以一致的方式处理树形结构中的所有对象 /*** 定义了所有对象必须实现的操作*/public interface IComponent {void add(IComponent component);void remove(IComponent component);ListIComponent getList();}/*** 定义了所有对象必须实现的操作*/ Data public abstract class Component implements IComponent{private String name;private String des;public Component(String name, String des) {this.name name;this.des des;}Overridepublic void add(IComponent component) {}Overridepublic void remove(IComponent component) {}} /*** 公司,Composite类也实现Component接口并包含其他Component对象的集合。*/ public class Company extends Component {private ListIComponent list new ArrayList();public Company(String name, String des) {super(name, des);}Overridepublic void add(IComponent component) {list.add(component);}Overridepublic void remove(IComponent component) {list.remove(component);}Overridepublic List getList() {return list;} }/*** 部门,Composite类也实现Component接口并包含其他Component对象的集合。*/ public class Department extends Component {private ListIComponent list new ArrayList();public Department(String name, String des) {super(name, des);}Overridepublic void add(IComponent component) {list.add(component);}Overridepublic void remove(IComponent component) {list.remove(component);}Overridepublic List getList() {return list;} }/*** 员工实现Component接口代表树中的叶子节点没有子节点也不需要管理其他节点*/ public class Staff extends Component {public Staff(String name, String des) {super(name, des);}Overridepublic List getList() {return null;} } 测试类 public class Client {public static void main(String[] args) {Component company new Company(某科技公司,提供软件服务);Component department new Department(财务部门,管理公司财务);Component department1 new Department(技术部门,管理公司财务);company.add(department);company.add(department1);department.add(new Staff(王某某,普通职员));department.add(new Staff(李某某,普通职员));department.add(new Staff(刘某某,财务主管));department1.add(new Staff(黄某某,普通职员));department1.add(new Staff(赵某某,普通职员));department1.add(new Staff(吴某某,技术主管));System.out.println(company);System.out.println(--------);ListComponent list company.getList();for (Component component : list){System.out.println(component);ListComponent list1 component.getList();for (Component co : list1){System.out.println(co);}System.out.println(--------);}} }执行结果 优点 简化客户端代码客户端可以统一处理所有类型的节点。易于扩展可以轻松添加新的叶子类型或树枝类型。适用于需要处理复杂树形结构的场景如文件系统、组织结构等。 缺点 需要较高的抽象性如果节点和叶子有很多差异就不适用于组合模式 外观模式 外观模式Facade Pattern 也叫过程模式属于结构型模式。外观模式为子系统中一组接口提供了一个一致性界面来隐藏系统的复杂性客户端只需要和这个接口发生关系即可无需关心子系统的内部实现类似于公司前台简化了客户端对复杂系统的操作隐藏内部实现细节降低了客户端与复杂子系统之间的耦合度。 结构 外观Facade: 提供一个简化的接口封装了系统的复杂性。外观模式的客户端通过与外观对象交互而无需直接与系统的各个组件打交道。 子系统Subsystem: 由多个相互关联的类组成负责系统的具体功能。外观对象通过调用这些子系统来完成客户端的请求。 客户端Client: 使用外观对象来与系统交互而不需要了解系统内部的具体实现。 优点 减少依赖客户端与子系统之间的依赖减少。提高灵活性子系统的内部变化不会影响客户端。增强安全性隐藏了子系统的内部实现只暴露必要的操作。 缺点 违反开闭原则对子系统的修改可能需要对外观类进行相应的修改。 使用建议 在需要简化复杂系统访问时使用外观模式。确保外观类提供的方法足够简单以便于客户端使用。避免过度使用外观模式以免隐藏过多的细节导致维护困难如果子系统比较简单就不要使用外观模式增加系统复杂度在维护一个遗留的大型项目时这个系统可能已经变的难以维护和扩展可以考虑使用外观模式开发一个外观类来提供系统遗留的比较清晰的接口与新系统进行交互提高复用性 子系统 /*** 后勤*/ public class Logistics {public void receive() {System.out.println(在后勤部领取工牌);}public void restitution(){System.out.println(在后勤部归还工牌);}}/*** 设备部*/ public class Equipment {public void receive(){System.out.println(在设备部领取电脑);}public void still(){System.out.println(在设备部归还电脑);}}/*** 网络部*/ public class Network {public void open(){System.out.println(在网络部开通网络);}public void close(){System.out.println(在网络部关闭网络);} } 外观 /*** 外观类*/ Data AllArgsConstructor public class Appearance {private Equipment equipment;private Logistics logistics;private Network network;public void employment(){System.out.println(办理入职手续);logistics.receive();equipment.receive();network.open();}public void quit(){System.out.println(办理离职手续);equipment.still();network.close();logistics.restitution();}}客户端 public class Client {public static void main(String[] args) {Appearance appearance new Appearance(new Equipment(), new Logistics(), new Network());appearance.employment();System.out.println(----------------);appearance.quit();} }享元模式 享元模式Flyweight Pattern 又称蝇量模式属于结构型模式享共享元对象运用共享技术有效地支持大量细粒度对象可以减少创建对象的数量以减少内存占用和提高性能。经典应用场景为String常量池、数据库连接池、缓冲池等等 结构 享元工厂Flyweight Factory: 负责创建和管理享元对象通常包含一个池缓存用于存储和复用已经创建的享元对象。 具体享元Concrete Flyweight: 实现了抽象享元接口包含了内部状态和外部状态。内部状态是可以被共享的而外部状态则由客户端传递。 抽象享元Flyweight: 定义了具体享元和非共享享元的接口通常包含了设置外部状态的方法。 客户端Client: 使用享元工厂获取享元对象并通过设置外部状态来操作享元对象。客户端通常不需要关心享元对象的具体实现。 享元模式的内部状态和外部状态 内部状态指对象共享出来的信息也就是存储在对象内部且不会随着环境改变的信息外部状态指会随着环境的改变而改变的、不可共享的信息以活字硬刷术为例汉字本身是不可变的内部状态汉字的字体是可变的外部状态 优点 减少内存消耗通过共享对象减少了内存中对象的数量。提高效率减少了对象创建的时间提高了系统效率。 缺点 增加系统复杂度需要分离内部状态和外部状态增加了设计和实现的复杂性。线程安全问题如果外部状态处理不当可能会引起线程安全问题。 使用建议 在创建大量相似对象时考虑使用享元模式。确保享元对象的内部状态是共享的而外部状态是独立于对象的。要明确区分内部状态和外部状态避免混淆。使用享元工厂来控制对象的创建和复用确保对象的一致性和完整性。 /*** 抽象享元,定义了具体享元和非共享享元的接口通常包含了设置外部状态的方法。*/ public interface Flyweight {public String test(String type);}/*** 具体享元实现了抽象享元接口包含了内部状态和外部状态。内部状态是可以被共享的而外部状态则由客户端传递。*/ Data AllArgsConstructor public class ConcreteFlyweight implements Flyweight {// 具体的汉字内部状态private String value;// 字体为外部状态Overridepublic String test(String type) {return type : value;} } /*** 享元工厂:负责创建和管理享元对象通常包含一个池缓存用于存储和复用已经创建的享元对象。*/ public class Factory {private MapString, Flyweight map new HashMap();public Flyweight getFlyweight(String key) {if (!map.containsKey(key)) {Flyweight flyweight new ConcreteFlyweight(key);map.put(key, flyweight);}return map.get(key);}// 获取集合元素个数public Integer size() {return map.size();}} 测试类 public class Client {public static void main(String[] args) {Factory factory new Factory();Random random new Random();StringBuilder sb new StringBuilder();StringBuilder sb1 new StringBuilder();for (int a 0; a 10; a) {int in random.nextInt(1000)20000;Character in1 (char) in;Flyweight flyweight factory.getFlyweight(in1.toString());sb.append(flyweight.test(楷体)).append(;);sb1.append(flyweight.test(宋体)).append(;);}System.out.println(sb);System.out.println(sb1);System.out.println(factory.size());}} 只生成了10个汉字对象 Integer 中使用到了享元模式Integer 中有一个缓存池范围为-128到127 代理模式 代理模式Proxy Pattern 属于结构型模式代理模式通过引入一个代理对象来控制对原对象的访问用一个类代表另一个类的功能代理对象在客户端和目标对象之间充当中介负责将客户端的请求转发给目标对象同时可以在转发请求前后进行额外的处理。代理模式解决的是在直接访问某些对象时可能遇到的问题例如对象创建成本高、需要安全控制或远程访问等。代理模式主要有三种静态代理、动态代理JDK代理、cglib代理可以在内存中动态的创建对象而不需要实现接口cglib代理也属于动态代理 结构 抽象主题Subject: 定义了真实主题和代理主题的共同接口这样在任何使用真实主题的地方都可以使用代理主题。 真实主题Real Subject: 实现了抽象主题接口是代理对象所代表的真实对象。客户端直接访问真实主题但在某些情况下可以通过代理主题来间接访问。 代理Proxy: 实现了抽象主题接口并持有对真实主题的引用。代理主题通常在真实主题的基础上提供一些额外的功能例如延迟加载、权限控制、日志记录等。 客户端Client: 使用抽象主题接口来操作真实主题或代理主题不需要知道具体是哪一个实现类。 注意事项 与适配器模式的区别适配器模式改变接口而代理模式不改变接口。与装饰器模式的区别装饰器模式用于增强功能代理模式用于控制访问。 优点 职责分离代理模式将访问控制与业务逻辑分离。扩展性可以灵活地添加额外的功能或控制。智能化可以智能地处理访问请求如延迟加载、缓存等。 缺点 性能开销增加了代理层可能会影响请求的处理速度。实现复杂性某些类型的代理模式实现起来可能较为复杂。 静态代理 静态代理 需要定义接口或者父类被代理的对象需要与代理对象一起实现相同的接口或者继承相同的父类 优点是可以在不修改目标对象的基础上对功能进行扩展 缺点是 因为代理对象需要和目标对象实现同样的接口所以会有很多代理类而且接口增加方法目标对象和代理对象都需要维护 /*** 公司抽象主题Subject:* 定义了真实主题和代理主题的共同接口这样在任何使用真实主题的地方都可以使用代理主题*/ public interface Company {// 发货void deliverGoods();}/*** 仓库真实主题Real Subject:* 实现了抽象主题接口是代理对象所代表的真实对象。客户端直接访问真实主题但在某些情况下可以通过代理主题来间接访问*/ public class Warehouse implements Company {Overridepublic void deliverGoods() {System.out.println(货物从仓库发出);}}/*** 销售代理Proxy:* 实现了抽象主题接口并持有对真实主题的引用。代理主题通常在真实主题的基础上提供一些额外的功能*/ Data AllArgsConstructor public class Sale implements Company{// 被代理对象private Warehouse warehouse;Overridepublic void deliverGoods() {// 可以实现一些额外的功能System.out.println(客户从销售经理订购货物);warehouse.deliverGoods();System.out.println(发货完成);} } 测试类 public class Client {public static void main(String[] args) {Company company new Sale(new Warehouse());company.deliverGoods();}} 调用的代理对象的方法最终执行的是被代理对象的方法 动态代理 动态代理 代理对象不需要实现接口但是目标对象要实现接口否则不能使用动态代理代理对象的生成利用了JDK的API动态的在内存中构建对象所以动态代理也叫做JDK代理、接口代理 /*** 动态代理*/ Data AllArgsConstructor public class DynamicProxy {// 维护一个目标对象private Object target;public Object getProxyInstance(){/*** public static Object newProxyInstance(ClassLoader loader,* Class?[] interfaces,* InvocationHandler h)* loader 是类加载器* interfaces 目标对象实现的接口类型* h 事件处理执行目标对象的方法时会触发事件处理器方法* InvocationHandler 是函数式接口可以使用lambda表达式简化*/return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),(proxy, method, args) - {System.out.println(jdk动态代理开始);// 调用目标方法Object invoke method.invoke(target, args);System.out.println(jdk动态代理结束);return invoke;});}}/*** 公司抽象主题Subject:* 定义了真实主题和代理主题的共同接口这样在任何使用真实主题的地方都可以使用代理主题*/ public interface Company {// 发货void deliverGoods();}/*** 仓库真实主题Real Subject:* 实现了抽象主题接口是代理对象所代表的真实对象。客户端直接访问真实主题但在某些情况下可以通过代理主题来间接访问*/ public class Warehouse implements Company {Overridepublic void deliverGoods() {System.out.println(货物从仓库发出);}} 测试类 public class Client {public static void main(String[] args) {Company proxyInstance (Company) new DynamicProxy(new Warehouse()).getProxyInstance();proxyInstance.deliverGoods();} }cglib代理 cglib代理 静态代理和JDK代理都要求目标对象实现一个接口但是有时候目标对象只是一个单独的类并没有实现任何接口这个时候可以使用目标对象子类来实现代理也就是cglib代理cglib代理也就叫做子类代理原理是在内存中构建一个目标对象的子类对象从而实现对目标对象功能的扩展也算是动态代理的一种Cglib 是一个强大的高性能的代码生成包,它可以在运行期扩展 java 类与实现 java 接口.它广泛的被许多 AOP 的框架使用,例如 SpringAOP实现方法拦截Cglib 包的底层是通过使用字节码处理框架 ASM 来转换字节码并生成新的类Cglib 代理因为需要生成目标对象的子类所以被代理的类不能是final类并且目标方法如果是final或者静态的就不会被拦截所以无法扩展 SpringAOP 目标对象需要实现接口用 JDK 代理目标对象不需要实现接口用 Cglib 代理 使用cglib需要引入对应的包 dependencygroupIdcglib/groupIdartifactIdcglib/artifactIdversion3.3.0/version/dependency示例代码 import lombok.AllArgsConstructor; import lombok.Data; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;Data AllArgsConstructor public class CglibProxy implements MethodInterceptor {// 目标对象private Object target;// 返回一个代理对象是目标对象 target 的子类对象public Object getInstance(){// 创建工具类Enhancer enhancer new Enhancer();// 设置父类enhancer.setSuperclass(target.getClass());// 设置回调函数为自己enhancer.setCallback(this);// 创建并返回子类对象return enhancer.create();}/*** param o: 代理对象* param method: 被代理方法* param objects: 方法入参* param methodProxy: CGLIB方法**/Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println(cglib代理开始);Object invoke method.invoke(target, objects);System.out.println(cglib代理结束);return invoke;}} /*** 仓库真实主题Real Subject:*/ public class Warehouse {public void deliverGoods() {System.out.println(货物从仓库发出);}}/*** 测试类*/ public class Client {public static void main(String[] args) {Company proxyInstance (Company) new DynamicProxy(new Warehouse()).getProxyInstance();proxyInstance.deliverGoods();} }如果使用的 Java 9以上的 JDK会出现以下报错 java.lang.reflect.InaccessibleObjectException--Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not opens java.lang to unnamed module 722c41f4 因为自 Java 9 开始引入它强制执行封装边界并且只允许明确导出的包进行访问。默认情况下java.lang和其他一些核心Java包都不会向unnamed模块开放。 解决方法 如果你正在编写一个需要使用反射来访问java.lang中类或接口的应用程序你需要将你的应用程序打包为一个模块并在模块声明中明确导出你需要反射访问的包。如果你正在编写一个Java应用程序并且需要使用反射来访问java.lang中的类或接口你可以在你的module-info.java文件中添加以下代码 --add-opens java.base/java.langALL-UNNAMED
http://www.hkea.cn/news/14336960/

相关文章:

  • html5 网站建设大厂县城乡建设局网站
  • 呼和浩特网站建设价位网上发布信息的网站怎么做的
  • 设计常去的网站企业网站设计苏州
  • 翻译网站建设wordpress图片盗链
  • 个人商城网站怎么做营销型网站的目标是
  • iis网站伪静态鲲鹏建设集团有限公司网站
  • 分类信息网站织梦模板地方网站优势
  • 网站备案填写电话号码谷德设计网gooood
  • 17网站一起做网店揭阳做网站用哪些软件
  • 网站开发基本流程网站关键词排名优化工具
  • 合肥商业网站建设费用北京网站建设知名公司排名
  • 沙河高端网站建设购物网站的建设的好处
  • 东莞专业网站建设服务微信公众号的子菜单网页怎么制作
  • 北京怎么样做网站公司部门分类
  • 2017年网站推广怎么做网站怎样做的有吸引力
  • 深圳网站建设者linux网站做301重定向
  • 怎么盗号网站怎么做ftp媒体库 wordpress
  • 医院网站建设台账百度 手机网站 收录
  • 网络营销从网站建设开始网站地图制作怎么做?
  • 免费地方门户网站源码重庆网站建设公司价钱
  • c 网站开发教程南昌模板建站定制
  • 网站优化怎么做 有什么技巧织梦律师网站模版
  • 奇网企业网站管理系统seo和点击付费的区别
  • 游戏网站风控怎么做全国工商登记网
  • 网站后台如何更改信誉好的唐山网站建设
  • 大连网站建设怎么做网站设计培训学校
  • 内蒙古呼和浩特网站建设强比网站建设
  • 平台式网站模板下载地址电商如何推广产品
  • 建设企业网站有什么好处六安头条网
  • 做电商网站需要多少钱商务网站的建设有哪几个步骤