php电商网站开发流程图网站设计建设方案
news/
2025/10/8 3:19:18/
文章来源:
php电商网站开发流程图,网站设计建设方案,房地产家居网络平台,静态网站管理系统文章目录从框架源码学习结构型设计模式适配器模式应用实例案例一#xff1a;dubbo框架日志适配器Logger接口日志实现类Logger适配器接口LoggerAdapter实现类Logger日志工厂桥接模式应用场景案例#xff1a;dubbo源码-远程调用模块channelHandler设计ChannelHandler是一个SPI拓…
文章目录从框架源码学习结构型设计模式适配器模式应用实例案例一dubbo框架日志适配器Logger接口日志实现类Logger适配器接口LoggerAdapter实现类Logger日志工厂桥接模式应用场景案例dubbo源码-远程调用模块channelHandler设计ChannelHandler是一个SPI拓展接口,用户可以定制自己的Handler抽象类桥接ChannelHandler并实现自己的HandlerChannelHandler实现类抽象类实现类组合模式装饰器模式案例apache common-collections源码List分析jdk List接口源码List装饰器抽象方法序列化装饰器抽象方法FixedSizeList源码LazyList实现类外观模式(门面模式)案例sl4j日志使用享元模式RocketMQ过滤器工厂创建Filter代理模式静态代理案例rocketmq中滚动记录文件先将日志记录到指定文件代理类实现动态代理JDK动态代理案例dubbo中jdk动态代理工厂实现CGLIB动态代理案例dubbo中cglib创建代理类javassist动态代码创建从框架源码学习结构型设计模式
模式包括结构型模式 这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。适配器模式Adapter Pattern 桥接模式Bridge Pattern 过滤器模式Filter、Criteria Pattern 组合模式Composite Pattern 装饰器模式Decorator Pattern 外观模式Facade Pattern 享元模式Flyweight Pattern 代理模式Proxy Pattern
适配器模式
使接口不兼容的那些类可以一起工作其别名为包装器(Wrapper)。最典型的例子如读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器再将读卡器插入笔记本这样就可以通过笔记本来读取内存卡
应用实例
JAVA JDK 1.1 提供了 Enumeration 接口而在 1.2 中提供了 Iterator 接口想要使用 1.2 的 JDK则要将以前系统的 Enumeration 接口转化为 Iterator 接口这时就需要适配器模式。
public class EnumerationAdapterE implements IteratorE {EnumerationE enumeration;public EnumerationAdapter(EnumerationE enumeration) {this.enumeration enumeration;}Overridepublic boolean hasNext() {return enumeration.hasMoreElements();}Overridepublic E next() {return enumeration.nextElement();}Overridepublic void remove() {throw new UnsupportedOperationException(remove);}
}
案例一dubbo框架日志适配器
dubbo中通过LoggerFactory日志工厂创建log对象流行的日志框架有log4j、sl4j、log4j2、logback等而他们创建日志的对象各不相同如果不用适配器直接在LoggerFactory上创建日志对象那么每新加入一个新的日志框架都需要去修改LoggerFactory类而利用适配器的话新加入的日志框架可以基于SPI实现LoggerAdapter接口实现对象创建逻辑并且通过Adapter封装统一的getLogger()、setLogger()、setLevel()统一方法然后通过LoggerFactory#setLoggerAdapter()方法将对象放入日志工厂中。 Logger接口
public interface Logger {/*** Logs a message with trace log level.** param msg log this message*/void trace(String msg);/*** Logs an error with trace log level.** param e log this cause*/void trace(Throwable e);/*** Logs an error with trace log level.** param msg log this message* param e log this cause*/void trace(String msg, Throwable e);/*** Logs a message with debug log level.** param msg log this message*/void debug(String msg);/*** Logs an error with debug log level.** param e log this cause*/void debug(Throwable e);/*** Logs an error with debug log level.** param msg log this message* param e log this cause*/void debug(String msg, Throwable e);/*** Logs a message with info log level.** param msg log this message*/void info(String msg);/*** Logs an error with info log level.** param e log this cause*/void info(Throwable e);/*** Logs an error with info log level.** param msg log this message* param e log this cause*/void info(String msg, Throwable e);/*** Logs a message with warn log level.** param msg log this message*/void warn(String msg);/*** Logs a message with warn log level.** param e log this message*/void warn(Throwable e);/*** Logs a message with warn log level.** param msg log this message* param e log this cause*/void warn(String msg, Throwable e);/*** Logs a message with error log level.** param msg log this message*/void error(String msg);/*** Logs an error with error log level.** param e log this cause*/void error(Throwable e);/*** Logs an error with error log level.** param msg log this message* param e log this cause*/void error(String msg, Throwable e);/*** Is trace logging currently enabled?** return true if trace is enabled*/boolean isTraceEnabled();/*** Is debug logging currently enabled?* * return true if debug is enabled*/boolean isDebugEnabled();/*** Is info logging currently enabled?** return true if info is enabled*/boolean isInfoEnabled();/*** Is warn logging currently enabled?** return true if warn is enabled*/boolean isWarnEnabled();/*** Is error logging currently enabled?** return true if error is enabled*/boolean isErrorEnabled();}日志实现类
public class Log4jLogger implements Logger {private static final String FQCN FailsafeLogger.class.getName();private final org.apache.log4j.Logger logger;public Log4jLogger(org.apache.log4j.Logger logger) {this.logger logger;}Overridepublic void trace(String msg) {logger.log(FQCN, Level.TRACE, msg, null);}Overridepublic void trace(Throwable e) {logger.log(FQCN, Level.TRACE, e null ? null : e.getMessage(), e);}Overridepublic void trace(String msg, Throwable e) {logger.log(FQCN, Level.TRACE, msg, e);}Overridepublic void debug(String msg) {logger.log(FQCN, Level.DEBUG, msg, null);}Overridepublic void debug(Throwable e) {logger.log(FQCN, Level.DEBUG, e null ? null : e.getMessage(), e);}Overridepublic void debug(String msg, Throwable e) {logger.log(FQCN, Level.DEBUG, msg, e);}Overridepublic void info(String msg) {logger.log(FQCN, Level.INFO, msg, null);}Overridepublic void info(Throwable e) {logger.log(FQCN, Level.INFO, e null ? null : e.getMessage(), e);}Overridepublic void info(String msg, Throwable e) {logger.log(FQCN, Level.INFO, msg, e);}Overridepublic void warn(String msg) {logger.log(FQCN, Level.WARN, msg, null);}Overridepublic void warn(Throwable e) {logger.log(FQCN, Level.WARN, e null ? null : e.getMessage(), e);}Overridepublic void warn(String msg, Throwable e) {logger.log(FQCN, Level.WARN, msg, e);}Overridepublic void error(String msg) {logger.log(FQCN, Level.ERROR, msg, null);}Overridepublic void error(Throwable e) {logger.log(FQCN, Level.ERROR, e null ? null : e.getMessage(), e);}Overridepublic void error(String msg, Throwable e) {logger.log(FQCN, Level.ERROR, msg, e);}Overridepublic boolean isTraceEnabled() {return logger.isTraceEnabled();}Overridepublic boolean isDebugEnabled() {return logger.isDebugEnabled();}Overridepublic boolean isInfoEnabled() {return logger.isInfoEnabled();}Overridepublic boolean isWarnEnabled() {return logger.isEnabledFor(Level.WARN);}Overridepublic boolean isErrorEnabled() {return logger.isEnabledFor(Level.ERROR);}}Logger适配器接口
SPI
public interface LoggerAdapter {/*** Get a logger** param key the returned logger will be named after clazz* return logger*/Logger getLogger(Class? key);/*** Get a logger** param key the returned logger will be named after key* return logger*/Logger getLogger(String key);/*** Get the current logging level** return current logging level*/Level getLevel();/*** Set the current logging level** param level logging level*/void setLevel(Level level);/*** Get the current logging file** return current logging file*/File getFile();/*** Set the current logging file** param file logging file*/void setFile(File file);
}LoggerAdapter实现类
public class Log4jLoggerAdapter implements LoggerAdapter {private File file;SuppressWarnings(unchecked)public Log4jLoggerAdapter() {try {org.apache.log4j.Logger logger LogManager.getRootLogger();if (logger ! null) {EnumerationAppender appenders logger.getAllAppenders();if (appenders ! null) {while (appenders.hasMoreElements()) {Appender appender appenders.nextElement();if (appender instanceof FileAppender) {FileAppender fileAppender (FileAppender) appender;String filename fileAppender.getFile();file new File(filename);break;}}}}} catch (Throwable t) {}}private static org.apache.log4j.Level toLog4jLevel(Level level) {if (level Level.ALL) {return org.apache.log4j.Level.ALL;}if (level Level.TRACE) {return org.apache.log4j.Level.TRACE;}if (level Level.DEBUG) {return org.apache.log4j.Level.DEBUG;}if (level Level.INFO) {return org.apache.log4j.Level.INFO;}if (level Level.WARN) {return org.apache.log4j.Level.WARN;}if (level Level.ERROR) {return org.apache.log4j.Level.ERROR;}// if (level Level.OFF)return org.apache.log4j.Level.OFF;}private static Level fromLog4jLevel(org.apache.log4j.Level level) {if (level org.apache.log4j.Level.ALL) {return Level.ALL;}if (level org.apache.log4j.Level.TRACE) {return Level.TRACE;}if (level org.apache.log4j.Level.DEBUG) {return Level.DEBUG;}if (level org.apache.log4j.Level.INFO) {return Level.INFO;}if (level org.apache.log4j.Level.WARN) {return Level.WARN;}if (level org.apache.log4j.Level.ERROR) {return Level.ERROR;}// if (level org.apache.log4j.Level.OFF)return Level.OFF;}Overridepublic Logger getLogger(Class? key) {return new Log4jLogger(LogManager.getLogger(key));}Overridepublic Logger getLogger(String key) {return new Log4jLogger(LogManager.getLogger(key));}Overridepublic Level getLevel() {return fromLog4jLevel(LogManager.getRootLogger().getLevel());}Overridepublic void setLevel(Level level) {LogManager.getRootLogger().setLevel(toLog4jLevel(level));}Overridepublic File getFile() {return file;}Overridepublic void setFile(File file) {}}Logger日志工厂
public class LoggerFactory {private static final ConcurrentMapString, FailsafeLogger LOGGERS new ConcurrentHashMap();private static volatile LoggerAdapter LOGGER_ADAPTER;// search common-used logging frameworksstatic {String logger System.getProperty(dubbo.application.logger, );switch (logger) {case slf4j:setLoggerAdapter(new Slf4jLoggerAdapter());break;case jcl:setLoggerAdapter(new JclLoggerAdapter());break;case log4j:setLoggerAdapter(new Log4jLoggerAdapter());break;case jdk:setLoggerAdapter(new JdkLoggerAdapter());break;case log4j2:setLoggerAdapter(new Log4j2LoggerAdapter());break;default:ListClass? extends LoggerAdapter candidates Arrays.asList(Log4jLoggerAdapter.class,Slf4jLoggerAdapter.class,Log4j2LoggerAdapter.class,JclLoggerAdapter.class,JdkLoggerAdapter.class);for (Class? extends LoggerAdapter clazz : candidates) {try {setLoggerAdapter(clazz.newInstance());break;} catch (Throwable ignored) {}}}}private LoggerFactory() {}public static void setLoggerAdapter(String loggerAdapter) {if (loggerAdapter ! null loggerAdapter.length() 0) {setLoggerAdapter(ExtensionLoader.getExtensionLoader(LoggerAdapter.class).getExtension(loggerAdapter));}}/*** Set logger provider** param loggerAdapter logger provider*/public static void setLoggerAdapter(LoggerAdapter loggerAdapter) {if (loggerAdapter ! null) {Logger logger loggerAdapter.getLogger(LoggerFactory.class.getName());logger.info(using logger: loggerAdapter.getClass().getName());LoggerFactory.LOGGER_ADAPTER loggerAdapter;for (Map.EntryString, FailsafeLogger entry : LOGGERS.entrySet()) {entry.getValue().setLogger(LOGGER_ADAPTER.getLogger(entry.getKey()));}}}/*** Get logger provider** param key the returned logger will be named after clazz* return logger*/public static Logger getLogger(Class? key) {return LOGGERS.computeIfAbsent(key.getName(), name - new FailsafeLogger(LOGGER_ADAPTER.getLogger(name)));}/*** Get logger provider** param key the returned logger will be named after key* return logger provider*/public static Logger getLogger(String key) {return LOGGERS.computeIfAbsent(key, k - new FailsafeLogger(LOGGER_ADAPTER.getLogger(k)));}/*** Get logging level** return logging level*/public static Level getLevel() {return LOGGER_ADAPTER.getLevel();}/*** Set the current logging level** param level logging level*/public static void setLevel(Level level) {LOGGER_ADAPTER.setLevel(level);}/*** Get the current logging file** return current logging file*/public static File getFile() {return LOGGER_ADAPTER.getFile();}}桥接模式
桥我们大家都熟悉顾名思义就是用来将河的两岸联系起来的。而此处的桥是用来将两个独立的结构联系起来而这两个被联系起来的结构可以独立的变化所有其他的理解只要建立在这个层面上就会比较容易。
它通过提供抽象化和实现化之间的桥接结构来实现二者的解耦。
优先文章链接
《菜鸟教程-桥接模式》《知乎-秒懂设计模式》《设计模式-桥接模式诺基亚我觉得我还能抢救下》
应用场景
按照手机分类有智能手机、按钮手机、翻盖手机等按照商品又有华为、小米、诺基亚等等
public class BridgeModel {/*** 品牌*/public interface Brand{void start();void shutdown();}/*** 手机抽象类*/public abstract class Phone{Brand brand;/*** 这段代码就是桥接思想将另一个类和抽象类组合* param brand*/public Phone(Brand brand) {this.brand brand;}void start(){this.brand.start();}void shutdown(){this.brand.shutdown();}}class HuaWei implements Brand{Overridepublic void start() {System.out.println(华为 开机);}Overridepublic void shutdown() {System.out.println(华为 关机);}}class XiaoMi implements Brand{Overridepublic void start() {System.out.println(小米 开机);}Overridepublic void shutdown() {System.out.println(小米 关机);}}class Nokia implements Brand{Overridepublic void start() {System.out.println(诺基亚 开机);}Overridepublic void shutdown() {System.out.println(诺基亚 关机);}}/*** 带键盘按钮手机*/class ButtonIphone extends Phone{public ButtonIphone(Brand brand) {super(brand);}}/*** 智能手机*/class SmartIphone extends Phone{public SmartIphone(Brand brand) {super(brand);}}Testpublic void runTest() {ButtonIphone buttonIphone new ButtonIphone(new Nokia());buttonIphone.start();buttonIphone.shutdown();SmartIphone huawei new SmartIphone(new HuaWei());huawei.start();huawei.shutdown();SmartIphone xiaomi new SmartIphone(new XiaoMi());xiaomi.start();xiaomi.shutdown();}}案例dubbo源码-远程调用模块channelHandler设计
ChannelHandler是一个SPI拓展接口,用户可以定制自己的Handler
SPI
public interface ChannelHandler {/*** on channel connected.** param channel channel.*/void connected(Channel channel) throws RemotingException;/*** on channel disconnected.** param channel channel.*/void disconnected(Channel channel) throws RemotingException;/*** on message sent.** param channel channel.* param message message.*/void sent(Channel channel, Object message) throws RemotingException;/*** on message received.** param channel channel.* param message message.*/void received(Channel channel, Object message) throws RemotingException;/*** on exception caught.** param channel channel.* param exception exception.*/void caught(Channel channel, Throwable exception) throws RemotingException;}抽象类桥接ChannelHandler并实现自己的Handler
public abstract class AbstractChannelHandlerDelegate implements ChannelHandlerDelegate {protected ChannelHandler handler;protected AbstractChannelHandlerDelegate(ChannelHandler handler) {Assert.notNull(handler, handler null);this.handler handler;}Overridepublic ChannelHandler getHandler() {if (handler instanceof ChannelHandlerDelegate) {return ((ChannelHandlerDelegate) handler).getHandler();}return handler;}Overridepublic void connected(Channel channel) throws RemotingException {handler.connected(channel);}Overridepublic void disconnected(Channel channel) throws RemotingException {handler.disconnected(channel);}Overridepublic void sent(Channel channel, Object message) throws RemotingException {handler.sent(channel, message);}Overridepublic void received(Channel channel, Object message) throws RemotingException {handler.received(channel, message);}Overridepublic void caught(Channel channel, Throwable exception) throws RemotingException {handler.caught(channel, exception);}
}ChannelHandler实现类
public class MockedChannelHandler implements ChannelHandler {// ConcurrentMapString, Channel channels new ConcurrentHashMapString, Channel();ConcurrentHashSetChannel channels new ConcurrentHashSetChannel();Overridepublic void connected(Channel channel) throws RemotingException {channels.add(channel);}Overridepublic void disconnected(Channel channel) throws RemotingException {channels.remove(channel);}Overridepublic void sent(Channel channel, Object message) throws RemotingException {channel.send(message);}Overridepublic void received(Channel channel, Object message) throws RemotingException {//echo channel.send(message);}Overridepublic void caught(Channel channel, Throwable exception) throws RemotingException {throw new RemotingException(channel, exception);}public SetChannel getChannels() {return Collections.unmodifiableSet(channels);}
}抽象类实现类
public class MultiMessageHandler extends AbstractChannelHandlerDelegate {public MultiMessageHandler(ChannelHandler handler) {super(handler);}SuppressWarnings(unchecked)Overridepublic void received(Channel channel, Object message) throws RemotingException {if (message instanceof MultiMessage) {MultiMessage list (MultiMessage) message;for (Object obj : list) {handler.received(channel, obj);}} else {handler.received(channel, message);}}
}组合模式
组合Composite Pattern模式的定义有时又叫作整体-部分Part-Whole模式它是一种将对象组合成树状的层次结构的模式用来表示“整体-部分”的关系使用户对单个对象和组合对象具有一致的访问性。
具体可以参考该文章http://c.biancheng.net/view/1373.html
装饰器模式
装饰器模式Decorator Pattern允许向一个现有的对象添加新的功能同时又不改变其结构。这种类型的设计模式属于结构型模式它是作为现有的类的一个包装。
这种模式创建了一个装饰类用来包装原有的类并在保持类方法签名完整性的前提下提供了额外的功能。
案例apache common-collections源码List分析
apache common-collections是对jdk collections功能的补充用了大量的装饰器设计模式一下摘取List为例
commons-collections使用介绍之List
jdk List接口源码
public interface ListE extends CollectionE {//继承了Collection接口int size();boolean isEmpty();boolean contains(Object o);IteratorE iterator();Object[] toArray();T T[] toArray(T[] a);boolean add(E e);boolean remove(Object o);boolean containsAll(Collection? c);boolean addAll(Collection? extends E c);boolean removeAll(Collection? c);boolean retainAll(Collection? c);boolean equals(Object o);int hashCode();default SpliteratorE spliterator() {return Spliterators.spliterator(this, Spliterator.ORDERED);}
}List装饰器抽象方法
public abstract class AbstractListDecorator extends AbstractCollectionDecorator implements List {protected AbstractListDecorator() {}protected AbstractListDecorator(List list) {super(list);}protected List getList() {return (List)this.getCollection();}public void add(int index, Object object) {this.getList().add(index, object);}public boolean addAll(int index, Collection coll) {return this.getList().addAll(index, coll);}public Object get(int index) {return this.getList().get(index);}public int indexOf(Object object) {return this.getList().indexOf(object);}public int lastIndexOf(Object object) {return this.getList().lastIndexOf(object);}public ListIterator listIterator() {return this.getList().listIterator();}public ListIterator listIterator(int index) {return this.getList().listIterator(index);}public Object remove(int index) {return this.getList().remove(index);}public Object set(int index, Object object) {return this.getList().set(index, object);}public List subList(int fromIndex, int toIndex) {return this.getList().subList(fromIndex, toIndex);}
}序列化装饰器抽象方法
public abstract class AbstractSerializableListDecorator extends AbstractListDecorator implements Serializable {private static final long serialVersionUID 2684959196747496299L;protected AbstractSerializableListDecorator(List list) {super(list);}private void writeObject(ObjectOutputStream out) throws IOException {out.defaultWriteObject();out.writeObject(this.collection);}private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {in.defaultReadObject();this.collection (Collection)in.readObject();}
}FixedSizeList源码
FixedSizeList修饰另一个列表防止添加/删除并且固定列表大小。add、remove、clear和retain操作是不被支持的set方法是允许的但是不会影响列表大小。
public class FixedSizeList extends AbstractSerializableListDecorator implements BoundedCollection {private static final long serialVersionUID -2218010673611160319L;public static List decorate(List list) {return new FixedSizeList(list);}protected FixedSizeList(List list) {super(list);}public boolean add(Object object) {throw new UnsupportedOperationException(List is fixed size);}public void add(int index, Object object) {throw new UnsupportedOperationException(List is fixed size);}public boolean addAll(Collection coll) {throw new UnsupportedOperationException(List is fixed size);}public boolean addAll(int index, Collection coll) {throw new UnsupportedOperationException(List is fixed size);}public void clear() {throw new UnsupportedOperationException(List is fixed size);}public Object get(int index) {return this.getList().get(index);}public int indexOf(Object object) {return this.getList().indexOf(object);}public Iterator iterator() {return UnmodifiableIterator.decorate(this.getCollection().iterator());}public int lastIndexOf(Object object) {return this.getList().lastIndexOf(object);}public ListIterator listIterator() {return new FixedSizeList.FixedSizeListIterator(this.getList().listIterator(0));}public ListIterator listIterator(int index) {return new FixedSizeList.FixedSizeListIterator(this.getList().listIterator(index));}public Object remove(int index) {throw new UnsupportedOperationException(List is fixed size);}public boolean remove(Object object) {throw new UnsupportedOperationException(List is fixed size);}public boolean removeAll(Collection coll) {throw new UnsupportedOperationException(List is fixed size);}public boolean retainAll(Collection coll) {throw new UnsupportedOperationException(List is fixed size);}public Object set(int index, Object object) {return this.getList().set(index, object);}public List subList(int fromIndex, int toIndex) {List sub this.getList().subList(fromIndex, toIndex);return new FixedSizeList(sub);}public boolean isFull() {return true;}public int maxSize() {return this.size();}static class FixedSizeListIterator extends AbstractListIteratorDecorator {protected FixedSizeListIterator(ListIterator iterator) {super(iterator);}public void remove() {throw new UnsupportedOperationException(List is fixed size);}public void add(Object object) {throw new UnsupportedOperationException(List is fixed size);}}
}LazyList实现类
LazyList修饰另一个列表当调用get方法时如果索引超出列表长度列表会自动增长我们可以通过一个工厂获得超出索引位置的值。LazyList和GrowthList都可以实现对修饰的列表进行增长但是LazyList发生在get时候而GrowthList发生在set和add时候我们也可以混合使用这两种列表。
public class LazyList extends AbstractSerializableListDecorator {private static final long serialVersionUID -1708388017160694542L;protected final Factory factory;public static List decorate(List list, Factory factory) {return new LazyList(list, factory);}protected LazyList(List list, Factory factory) {super(list);if (factory null) {throw new IllegalArgumentException(Factory must not be null);} else {this.factory factory;}}public Object get(int index) {int size this.getList().size();Object object;if (index size) {object this.getList().get(index);if (object null) {object this.factory.create();this.getList().set(index, object);return object;} else {return object;}} else {for(int i size; i index; i) {this.getList().add((Object)null);}object this.factory.create();this.getList().add(object);return object;}}public List subList(int fromIndex, int toIndex) {List sub this.getList().subList(fromIndex, toIndex);return new LazyList(sub, this.factory);}
}外观模式(门面模式)
其核心为外部与一个子系统的通信必须通过一个统一的外观对象进行使得子系统更易于使用。用一张图来表示门面模式的结构为
简单来说该模式就是把一些复杂的流程封装成一个接口供给外部用户更简单的使用。这个模式中设计到3个角色。
1门面角色外观模式的核心。它被客户角色调用它熟悉子系统的功能。内部根据客户角色的需求预定了几种功能的组合模块。
2子系统模块角色实现了子系统的功能。它对客户角色和 Facade 是未知的。它内部可以有系统内的相互交互也可以由供外界调用的接口。
3客户角色通过调用 Facede 来完成要实现的功能。
日志门面抽象层日志实现JCL(java.util.logging)JULSLF4jlog4j、log4j2、logback
slf4j的作用只要所有代码都使用门面对象slf4j我们就不需要关心其具体实现最终所有地方使用一种具体实现即可更换、维护都非常方便。
sl4j作用以及原理
案例sl4j日志使用
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class HelloWorld {public static void main(String[] args) {// HelloWorld.class 就是你要打印的指定类的日志// 如果你想在其它类中打印那就把 HelloWorld.class 替换成目标类名.class 即可。Logger logger LoggerFactory.getLogger(HelloWorld.class); logger.info(Hello World);}
}享元模式
享元模式Flyweight Pattern主要用于减少创建对象的数量以减少内存占用和提高性能。
RocketMQ过滤器工厂创建Filter
public class FilterFactory {public static final FilterFactory INSTANCE new FilterFactory();protected static final MapString, FilterSpi FILTER_SPI_HOLDER new HashMapString, FilterSpi(4);static {FilterFactory.INSTANCE.register(new SqlFilter());}/*** Register a filter.* br* Note:* li1. Filter registered will be used in broker server, so take care of its reliability and performance./li*/public void register(FilterSpi filterSpi) {if (FILTER_SPI_HOLDER.containsKey(filterSpi.ofType())) {throw new IllegalArgumentException(String.format(Filter spi type(%s) already exist!, filterSpi.ofType()));}FILTER_SPI_HOLDER.put(filterSpi.ofType(), filterSpi);}/*** Un register a filter.*/public FilterSpi unRegister(String type) {return FILTER_SPI_HOLDER.remove(type);}/*** Get a filter registered, null if none exist.*/public FilterSpi get(String type) {return FILTER_SPI_HOLDER.get(type);}代理模式
由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时访问对象不适合或者不能直接引用目标对象代理对象作为访问对象和目标对象之间的中介。
静态代理
静态代理的代理关系在编译期间就已经确定了的。它适合于代理类较少且确定的情况
案例rocketmq中滚动记录文件先将日志记录到指定文件代理类实现 private static InternalLogger createLogger(final String loggerName) {String clientLogLevel System.getProperty(CLIENT_LOG_LEVEL, INFO);boolean additive true.equalsIgnoreCase(System.getProperty(CLIENT_LOG_ADDITIVE));InternalLogger logger InternalLoggerFactory.getLogger(loggerName);InnerLoggerFactory.InnerLogger innerLogger (InnerLoggerFactory.InnerLogger) logger;Logger realLogger innerLogger.getLogger();//if (rocketmqClientAppender null) {// createClientAppender();//}realLogger.addAppender(new AppenderProxy());realLogger.setLevel(Level.toLevel(clientLogLevel));realLogger.setAdditivity(additive);return logger;} static class AppenderProxy extends Appender {private Appender proxy;Overrideprotected void append(LoggingEvent event) {if (null proxy) {proxy ClientLogger.createClientAppender();}proxy.doAppend(event);}Overridepublic void close() {if (null ! proxy) {proxy.close();}}}动态代理
代理类在程序运行时创建的代理方式叫动态代理
JDK动态代理
JDK动态代理是基于接口的方式换句话来说就是代理类和目标类都实现同一个接口,利用jdk自带的包通过目标类实现类创建代理类具体参考我另一个博客jdk、cglib动态代理代码示例
案例dubbo中jdk动态代理工厂实现
public class JdkProxyFactory extends AbstractProxyFactory {OverrideSuppressWarnings(unchecked)public T T getProxy(InvokerT invoker, Class?[] interfaces) {return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvokerInvocationHandler(invoker));}Overridepublic T InvokerT getInvoker(T proxy, ClassT type, URL url) {return new AbstractProxyInvokerT(proxy, type, url) {Overrideprotected Object doInvoke(T proxy, String methodName,Class?[] parameterTypes,Object[] arguments) throws Throwable {Method method proxy.getClass().getMethod(methodName, parameterTypes);return method.invoke(proxy, arguments);}};}
}其他相关类源码
public interface Node {URL getUrl();boolean isAvailable();void destroy();
}public interface InvokerT extends Node {ClassT getInterface();Result invoke(Invocation invocation) throws RpcException;
}public abstract class AbstractProxyInvokerT implements InvokerT {Logger logger LoggerFactory.getLogger(AbstractProxyInvoker.class);private final T proxy;private final ClassT type;private final URL url;public AbstractProxyInvoker(T proxy, ClassT type, URL url) {if (proxy null) {throw new IllegalArgumentException(proxy null);}if (type null) {throw new IllegalArgumentException(interface null);}if (!type.isInstance(proxy)) {throw new IllegalArgumentException(proxy.getClass().getName() not implement interface type);}this.proxy proxy;this.type type;this.url url;}Overridepublic ClassT getInterface() {return type;}Overridepublic URL getUrl() {return url;}Overridepublic boolean isAvailable() {return true;}Overridepublic void destroy() {}Overridepublic Result invoke(Invocation invocation) throws RpcException {try {Object value doInvoke(proxy, invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());CompletableFutureObject future wrapWithFuture(value);CompletableFutureAppResponse appResponseFuture future.handle((obj, t) - {AppResponse result new AppResponse();if (t ! null) {if (t instanceof CompletionException) {result.setException(t.getCause());} else {result.setException(t);}} else {result.setValue(obj);}return result;});return new AsyncRpcResult(appResponseFuture, invocation);} catch (InvocationTargetException e) {if (RpcContext.getContext().isAsyncStarted() !RpcContext.getContext().stopAsync()) {logger.error(Provider async started, but got an exception from the original method, cannot write the exception back to consumer because an async result may have returned the new thread., e);}return AsyncRpcResult.newDefaultAsyncResult(null, e.getTargetException(), invocation);} catch (Throwable e) {throw new RpcException(Failed to invoke remote proxy method invocation.getMethodName() to getUrl() , cause: e.getMessage(), e);}}private CompletableFutureObject wrapWithFuture(Object value) {if (RpcContext.getContext().isAsyncStarted()) {return ((AsyncContextImpl)(RpcContext.getContext().getAsyncContext())).getInternalFuture();} else if (value instanceof CompletableFuture) {return (CompletableFutureObject) value;}return CompletableFuture.completedFuture(value);}protected abstract Object doInvoke(T proxy, String methodName, Class?[] parameterTypes, Object[] arguments) throws Throwable;Overridepublic String toString() {return getInterface() - (getUrl() null ? : getUrl().toString());}}public class InvokerInvocationHandler implements InvocationHandler {private static final Logger logger LoggerFactory.getLogger(InvokerInvocationHandler.class);private final Invoker? invoker;private ConsumerModel consumerModel;private URL url;private String protocolServiceKey;public InvokerInvocationHandler(Invoker? handler) {this.invoker handler;this.url invoker.getUrl();String serviceKey this.url.getServiceKey();this.protocolServiceKey this.url.getProtocolServiceKey();if (serviceKey ! null) {this.consumerModel ApplicationModel.getConsumerModel(serviceKey);}}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (method.getDeclaringClass() Object.class) {return method.invoke(invoker, args);}String methodName method.getName();Class?[] parameterTypes method.getParameterTypes();if (parameterTypes.length 0) {if (toString.equals(methodName)) {return invoker.toString();} else if ($destroy.equals(methodName)) {invoker.destroy();return null;} else if (hashCode.equals(methodName)) {return invoker.hashCode();}} else if (parameterTypes.length 1 equals.equals(methodName)) {return invoker.equals(args[0]);}RpcInvocation rpcInvocation new RpcInvocation(method, invoker.getInterface().getName(), protocolServiceKey, args);String serviceKey invoker.getUrl().getServiceKey();rpcInvocation.setTargetServiceUniqueName(serviceKey);// invoker.getUrl() returns consumer url.RpcContext.setRpcContext(invoker.getUrl());if (consumerModel ! null) {rpcInvocation.put(Constants.CONSUMER_MODEL, consumerModel);rpcInvocation.put(Constants.METHOD_MODEL, consumerModel.getMethodModel(method));}return invoker.invoke(rpcInvocation).recreate();}
}SPI(javassist)
public interface ProxyFactory {/*** create proxy.** param invoker* return proxy*/Adaptive({PROXY_KEY})T T getProxy(InvokerT invoker) throws RpcException;/*** create proxy.** param invoker* return proxy*/Adaptive({PROXY_KEY})T T getProxy(InvokerT invoker, boolean generic) throws RpcException;/*** create invoker.** param T* param proxy* param type* param url* return invoker*/Adaptive({PROXY_KEY})T InvokerT getInvoker(T proxy, ClassT type, URL url) throws RpcException;
public abstract class AbstractProxyFactory implements ProxyFactory {private static final Class?[] INTERNAL_INTERFACES new Class?[]{EchoService.class, Destroyable.class};Overridepublic T T getProxy(InvokerT invoker) throws RpcException {return getProxy(invoker, false);}Overridepublic T T getProxy(InvokerT invoker, boolean generic) throws RpcException {SetClass? interfaces new HashSet();String config invoker.getUrl().getParameter(INTERFACES);if (config ! null config.length() 0) {String[] types COMMA_SPLIT_PATTERN.split(config);for (String type : types) {// TODO can we load successfully for a different classloader?.interfaces.add(ReflectUtils.forName(type));}}if (generic) {if (!GenericService.class.isAssignableFrom(invoker.getInterface())) {interfaces.add(com.alibaba.dubbo.rpc.service.GenericService.class);}try {// find the real interface from urlString realInterface invoker.getUrl().getParameter(Constants.INTERFACE);interfaces.add(ReflectUtils.forName(realInterface));} catch (Throwable e) {// ignore}}interfaces.add(invoker.getInterface());interfaces.addAll(Arrays.asList(INTERNAL_INTERFACES));return getProxy(invoker, interfaces.toArray(new Class?[0]));}public abstract T T getProxy(InvokerT invoker, Class?[] types);}CGLIB动态代理
CGLib动态代理是代理类去继承目标类然后重写其中目标类的方法
案例dubbo中cglib创建代理类 Testpublic void testCglibProxy() throws Exception {ITest test (ITest) Proxy.getProxy(ITest.class).newInstance((proxy, method, args) - {System.out.println(method.getName());return null;});Enhancer enhancer new Enhancer();enhancer.setSuperclass(test.getClass());enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) - null);try {enhancer.create();} catch (IllegalArgumentException e) {e.printStackTrace();Assertions.fail();}}javassist动态代码创建
javassist的强大之处在于它操作字节码的能力可以动态的修改类加载类添加删除字段、方法等操作。当然也可以实现动态代理
简单使用案例
public class JavassistProxyFactory extends AbstractProxyFactory {OverrideSuppressWarnings(unchecked)public T T getProxy(InvokerT invoker, Class?[] interfaces) {return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));}Overridepublic T InvokerT getInvoker(T proxy, ClassT type, URL url) {// TODO Wrapper cannot handle this scenario correctly: the classname contains $final Wrapper wrapper Wrapper.getWrapper(proxy.getClass().getName().indexOf($) 0 ? proxy.getClass() : type);return new AbstractProxyInvokerT(proxy, type, url) {Overrideprotected Object doInvoke(T proxy, String methodName,Class?[] parameterTypes,Object[] arguments) throws Throwable {return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);}};}
动态字节码生成 public static Wrapper getWrapper(Class? c) {while (ClassGenerator.isDynamicClass(c)) // can not wrapper on dynamic class.{c c.getSuperclass();}if (c Object.class) {return OBJECT_WRAPPER;}return WRAPPER_MAP.computeIfAbsent(c, Wrapper::makeWrapper);}private static Wrapper makeWrapper(Class? c) {if (c.isPrimitive()) {throw new IllegalArgumentException(Can not create wrapper for primitive type: c);}String name c.getName();ClassLoader cl ClassUtils.getClassLoader(c);StringBuilder c1 new StringBuilder(public void setPropertyValue(Object o, String n, Object v){ );StringBuilder c2 new StringBuilder(public Object getPropertyValue(Object o, String n){ );StringBuilder c3 new StringBuilder(public Object invokeMethod(Object o, String n, Class[] p, Object[] v) throws InvocationTargetException.class.getName() { );c1.append(name).append( w; try{ w (().append(name).append()$1); }catch(Throwable e){ throw new IllegalArgumentException(e); });c2.append(name).append( w; try{ w (().append(name).append()$1); }catch(Throwable e){ throw new IllegalArgumentException(e); });c3.append(name).append( w; try{ w (().append(name).append()$1); }catch(Throwable e){ throw new IllegalArgumentException(e); });MapString, Class? pts new HashMap(); // property name, property typesMapString, Method ms new LinkedHashMap(); // method desc, Method instanceListString mns new ArrayList(); // method names.ListString dmns new ArrayList(); // declaring method names.// get all public field.for (Field f : c.getFields()) {String fn f.getName();Class? ft f.getType();if (Modifier.isStatic(f.getModifiers()) || Modifier.isTransient(f.getModifiers())) {continue;}c1.append( if( $2.equals(\).append(fn).append(\) ){ w.).append(fn).append().append(arg(ft, $3)).append(; return; });c2.append( if( $2.equals(\).append(fn).append(\) ){ return ($w)w.).append(fn).append(; });pts.put(fn, ft);}Method[] methods c.getMethods();// get all public method.boolean hasMethod hasMethods(methods);if (hasMethod) {c3.append( try{);for (Method m : methods) {//ignore Objects method.if (m.getDeclaringClass() Object.class) {continue;}String mn m.getName();c3.append( if( \).append(mn).append(\.equals( $2 ) );int len m.getParameterTypes().length;c3.append( ).append( $3.length ).append(len);boolean overload false;for (Method m2 : methods) {if (m ! m2 m.getName().equals(m2.getName())) {overload true;break;}}if (overload) {if (len 0) {for (int l 0; l len; l) {c3.append( ).append( $3[).append(l).append(].getName().equals(\).append(m.getParameterTypes()[l].getName()).append(\));}}}c3.append( ) { );if (m.getReturnType() Void.TYPE) {c3.append( w.).append(mn).append(().append(args(m.getParameterTypes(), $4)).append();).append( return null;);} else {c3.append( return ($w)w.).append(mn).append(().append(args(m.getParameterTypes(), $4)).append(););}c3.append( });mns.add(mn);if (m.getDeclaringClass() c) {dmns.add(mn);}ms.put(ReflectUtils.getDesc(m), m);}c3.append( } catch(Throwable e) { );c3.append( throw new java.lang.reflect.InvocationTargetException(e); );c3.append( });}c3.append( throw new NoSuchMethodException.class.getName() (\Not found method \\\\$2\\\\ in class c.getName() .\); });// deal with get/set method.Matcher matcher;for (Map.EntryString, Method entry : ms.entrySet()) {String md entry.getKey();Method method entry.getValue();if ((matcher ReflectUtils.GETTER_METHOD_DESC_PATTERN.matcher(md)).matches()) {String pn propertyName(matcher.group(1));c2.append( if( $2.equals(\).append(pn).append(\) ){ return ($w)w.).append(method.getName()).append((); });pts.put(pn, method.getReturnType());} else if ((matcher ReflectUtils.IS_HAS_CAN_METHOD_DESC_PATTERN.matcher(md)).matches()) {String pn propertyName(matcher.group(1));c2.append( if( $2.equals(\).append(pn).append(\) ){ return ($w)w.).append(method.getName()).append((); });pts.put(pn, method.getReturnType());} else if ((matcher ReflectUtils.SETTER_METHOD_DESC_PATTERN.matcher(md)).matches()) {Class? pt method.getParameterTypes()[0];String pn propertyName(matcher.group(1));c1.append( if( $2.equals(\).append(pn).append(\) ){ w.).append(method.getName()).append(().append(arg(pt, $3)).append(); return; });pts.put(pn, pt);}}c1.append( throw new NoSuchPropertyException.class.getName() (\Not found property \\\\$2\\\\ field or setter method in class c.getName() .\); });c2.append( throw new NoSuchPropertyException.class.getName() (\Not found property \\\\$2\\\\ field or getter method in class c.getName() .\); });// make classlong id WRAPPER_CLASS_COUNTER.getAndIncrement();ClassGenerator cc ClassGenerator.newInstance(cl);cc.setClassName((Modifier.isPublic(c.getModifiers()) ? Wrapper.class.getName() : c.getName() $sw) id);cc.setSuperClass(Wrapper.class);cc.addDefaultConstructor();cc.addField(public static String[] pns;); // property name array.cc.addField(public static Map.class.getName() pts;); // property type map.cc.addField(public static String[] mns;); // all method name array.cc.addField(public static String[] dmns;); // declared method name array.for (int i 0, len ms.size(); i len; i) {cc.addField(public static Class[] mts i ;);}cc.addMethod(public String[] getPropertyNames(){ return pns; });cc.addMethod(public boolean hasProperty(String n){ return pts.containsKey($1); });cc.addMethod(public Class getPropertyType(String n){ return (Class)pts.get($1); });cc.addMethod(public String[] getMethodNames(){ return mns; });cc.addMethod(public String[] getDeclaredMethodNames(){ return dmns; });cc.addMethod(c1.toString());cc.addMethod(c2.toString());cc.addMethod(c3.toString());try {Class? wc cc.toClass();// setup static field.wc.getField(pts).set(null, pts);wc.getField(pns).set(null, pts.keySet().toArray(new String[0]));wc.getField(mns).set(null, mns.toArray(new String[0]));wc.getField(dmns).set(null, dmns.toArray(new String[0]));int ix 0;for (Method m : ms.values()) {wc.getField(mts ix).set(null, m.getParameterTypes());}return (Wrapper) wc.newInstance();} catch (RuntimeException e) {throw e;} catch (Throwable e) {throw new RuntimeException(e.getMessage(), e);} finally {cc.release();ms.clear();mns.clear();dmns.clear();}}优秀文章菜鸟教程
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/931077.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!