相关设计模式
- 适配器模式
- 模板方法模式
- 策略模式
- 组合模式
- 代理模式(使用Cglib的动态代理)
适配器模式
旧的类无法被删除和修改,在新的方法中对其进行方法的调用和前后进行操作
继承方式
//被适配的类
public class AdapterClass{
public void handleMethod(){
System.out.println("this is method to be handled")
}
}
//适配器接口
public interface Adapter{
void handle();
}
//适配器实现类
public class AdapterImpl extends AdapterClass implements Adapter{
@Override
public void handle(){
super.handleMethod();
}
}
//测试类
public class Test{
public static void main(Stirng[] args){
Adapter adapter = new AdapterImpl();
adapter.handle();
}
}
组合方式
//被适配的类
public class AdapterClass{
public void handleMethod(){
System.out.println("this is method to be handled")
}
}
//适配器接口
public interface Adapter{
void handle();
}
//适配器实现类
public class AdapterImpl implements Adapter{
private AdapterClass adapterClass;
public AdapterImpl(AdapterClass adapterClass){
this.adapterClass = adapterClass;
}
@Override
public void handle(){
this.adapterClass.handleMethod();
}
}
//测试类
public class Test{
public static void main(Stirng[] args){
AdapterClass adapterClass = new AdapterClass();
Adapter adapter = new AdapterImpl(adapterClass);
adapter.handle();
}
}
模板方法模式
模板方法的构成
- 抽象的基类以及其中定义的若干个抽象方法和一个final方法
- 定义为final是为了不让子类复写方法,改变实现逻辑
- 实现了抽象基类的具体的类,完成对抽象方法的实现
//抽象基类
public abstract class AbstractDatabaseExcecutor{
abstract void openConnection();
abstract String getResultSet();
abstract void closeConnection();
//为什么要定义为final是为了不让子类复写方法,改变实现逻辑
public final void execute(){
openConnection();
getResultSet();
closeConnection();
}
}
//具体实现类1
public class MysqlDatabaseExcutor extends AbstractDatabaseExcecuto{
@Override
void openConnection(){
System.out.println("mysql open conneciton")
}
@Override
String getResultSet(){
System.out.println("mysql result set")
}
@Override
void closeConnection(){
System.out.println("mysql close connection")
}
}
//具体实现类2
public class OracleDatabaseExcutor extends AbstractDatabaseExcecuto{
@Override
void openConnection(){
System.out.println("oracle open conneciton")
}
@Override
String getResultSet(){
System.out.println("oracle result set")
}
@Override
void closeConnection(){
System.out.println("oracle close connection")
}
}
//测试类
public class Test{
public static void main(Stirng[] args){
AbstractDatabaseExcecuto excutor = new MysqkDatabaseExcutor();
excutor.execute();
excutor = new OracleDatabaseExcutor();
excutor.execute();
}
}
策略模式
有一个抽象的接口,这个接口只定义了一个模型,不提供具体的实现,不同实现类有不同的实现
//抽象类
public interface AbstractStrategy{
int calc(int x, int y);
}
//加法实现类
public class AddStrategy implements AbstractStrategy{
@Override
public int calc(int x, int y){
return x + y;
}
}
//减法实现类
public class MinusStrategy implements AbstractStratgy{
@Override
public int calc(int x, int y){
return x - y;
}
}
//乘法实现类
public class MultiStrategy implements AbstractStrategy{
@Override
public int calc(int x, int y){
return x * y;
}
}
//环境类
public class Context{
private AbstractStrategy abstractStrategy;
public Context(AbstractStrategy abstractStrategy){
this.abstractStrategy = abstractStrategy;
}
public void excecute(int x, int y){
int calc = this.abstractStrategy.calc(x,y);
System.out.println(calc);
}
}
//测试类
public class test{
public static void main(Stirng[] args){
Context context = new Context(new AddStrategy());
context.excute(10,20);
Context context = new Context(new MinusStrategy());
context.excute(10,20);
Context context = new Context(new MultiStrategy());
context.excute(10,20);
}
}
组合模式
有一个篮子,篮子里承装任意多的对象,要把篮子里的任意对象遍历出来
public abstract class Component{
private String name;
public String getName(){
return name;
}
public Component(String name){
this.name = name;
}
//protected
protected abstract void dispaly();
}
public class Product extends Component{
public Product(String name){
super(name);
}
@Override
protected void display(){
System.out.println("the name of product is"+ this.getName());
}
}
public class Box extends Componnet{
private List<Component> productList = new ArrayList<>();
public void addProduct(Component component){
this.product.add(component);
}
public void removeProduct(Component component){
this.product.remove(component);
}
public Box(String name){
super(name);
}
@Override
protected void display(){
for(Component component : productList){
component.display();
}
}
}
//手推车里放入了商品,打印手推车中的商品
public class client{
public static void main(String[] args){
Box box = new Box("小推车");
Component c1 = new Product("牙膏");
Component c2 = new Product("肥皂");
Component c3 = new Product("牙刷");
box.addProcuct(c1);
box.addProcuct(c2);
box.addProcuct(c3);
box.display();
}
}
代理模式(JDK动态代理、Cglib的动态代理)
代理某个类,在它的方法实现前后进行一些操作(增强) 包括动态代理和静态代理
动态代理:
c JDK动态代理
public interface Target{
void handle();
}
public class TargetImpl implements Target{
@Override
public void handle(){
System.out.println("I can handle something");
}
}
/**
代理类
**/
public class TargetHandler implements InvocatioinHandler{
//被代理的类
private Object target;
public TargetHandler(Object target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
//方法前面操作
Object invoke = method.invoke(target,args);
//方法后面操作
return invoke;
}
}
public class Client{
public static void main(String[] args){
Target target = new TargetImpl();
InvocatioinHandler handler = new TargetHandler(target);
//代理对象 对象名{$Proxy0@502},非真实对象
Target o = Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getIntefaces(),handler)
o.handle();
}
}
Cglib动态代理
public class User{
public void userMethod(){
System.out.println("I am a user");
}
}
//选择使用spring中的cgblib
public class UserMethodIntercepter implements MethodIntercepter{
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy){
return methodProxy.invokeSuper(0,objects);
}
}
public class Client{
public static void main(String[] args){
//spring的,proxy.Enhancer
Enhancer enhancer = new Enhancer();
//让其继承一个类
enhancer.setSuperclass(User.class);
enhancer.setCallbacek(new UserMethodIntercepter());
User u = (User)enhancer.create();
user.userMethod();
}
}
两种代理的区别
JDK要实现一个接口,CGLIB不要求实现一个接口,但是由于要生成一个子类,所以类不能被fianl修饰
反射相关API讲解
public class Student{
private void sayHello(String name){
System.out.println("hello" + name);
}
}
public class Client{
public static void main(String[] args) throws NoSuchMethodException{
Student student= new Student();
Class<?> clazz = Student.class;
Method method = clazz.getDeclareMehod("sayHello",String.calss);
//设置允许
method.setAccessibale(true);
//参数数组
String[] strings = new String[]{"zhangsan"};
method.invoke(student,strings);
}
}
//如果将整个main方法移入到student类中,那么无需设置axxessibale就可以访问,因为main本身就在Student类中
分析SpringMvc中重要的类和组件
基于HttpServlet的API的一层封装
- FrameworkServlet
- DispatcherServlet
- HandlerInterceptor
- HandlerInteceptorAdapter
- HandlerMapping
- HandlerMethod
- HandlerAdapter
- MethodParameter
- HandlerMethodArgumentResolver
- HandlerMethodArgumentResolverComposite
- RequestResponseBodyMethodProcessor
FrameworkServlet
//处理web请求的一般过程是继承HttpServlet然后实现其中的doPost(post请求)和doGet方法(get请求)
public abstract class HttpServlet extends GenericServlet{
....
}
//查找实现了doGet方法的类,ctrl+T,找到了FrameworkServlet
//它继承了HttpServlet实现了doGet方法,它在springframework.web.servlet包中,请求就正式转入了spring的控制
DispatcherServlet
//也在org.springframework.web.servlet中,根据请求找到处理请求的组件(controller)
//提供便捷的映射和异常处理的公共组件
HandlerInterceptor
拦截器顶层的实现接口,对请求的若干个阶段进行拦截
//jdk1.8之后的default关键字,实现此接口可以不用实现所有的方法
public interface HandlerInterceptor {
//请求开始之前
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
//请求结束之后,画面渲染之前
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
//画面渲染之后(有的时候画面不存在,如modelAndView为空的情况)
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
HandlerInterceptorAdapter
此类的作用,如果直接实现HandlerInterceptor就要重写所有方法,实现HandlerInterceptorAdapter方法不需要重写所有方法,JDK1.8的default关键字已实现,作用变为了兼容一些老接口
public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
@Override
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
}
@Override
public void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
@Override
public void afterConcurrentHandlingStarted(
HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
}
}
public interface AsyncHandlerInterceptor extends HandlerInterceptor {
/**
* Called instead of {@code postHandle} and {@code afterCompletion}, when
* the a handler is being executed concurrently.
* <p>Implementations may use the provided request and response but should
* avoid modifying them in ways that would conflict with the concurrent
* execution of the handler. A typical use of this method would be to
* clean up thread-local variables.
*/
void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception;
}
HandlerMappping
处理请求到处理器的映射的作用,处理@RequestMapping等注解的方法/类与请求URL的映射 接口
//MatchableHandlerMapping繼承了HandlerMappping接口
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping
implements MatchableHandlerMapping, EmbeddedValueResolverAware {
....
}
HandlerMethod
可以理解为RequestMappingHandlerMapping映射出的方法,即类似@RequestMapping注解的方法 方法的元信息
HandlerAdapter
适配器模式,为什么是适配器模式,这个adapter判断是通过继承controller方法进行的处理 还是通过注解的方式
//在直接大量出现之前都是要实现该接口,重写该方法
@FunctionalInterfa ce
public interface Controller {
@Nullable
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
MethodParameter
封装了注解了@RequstMapping的方法的请求参数,请求参数的注解
HandlerMethodArgumentResolver
对请求参数进行处理
public interface HandlerMethodArgumentResolver {
//判断传入的MethodParameter是否能够被当前的HandlerMethodArgumentResolver执行
//eg:PathvariableMapMethodArgumentResolver
boolean supportsParameter(MethodParameter parameter);
//supportsParameter返回为true时调用该方法,同时将请求参数转到参数中
@Nullable
Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
}
HandlerMethodArgumentResolverComposite
使用了组合设计模式,组合了HandlerMethodArgumentResolver,封装了HandlerMethodArgumentResolver一系列的实现器,方便用来方便遍历解析器集合,可以理解为一个HandlerMethodArgumentResolver的容器
public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgumentResolver {
protected final Log logger = LogFactory.getLog(getClass());
private final List<HandlerMethodArgumentResolver> argumentResolvers = new LinkedList<>();
private final Map<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache =
new ConcurrentHashMap<>(256);
/**
* Add the given {@link HandlerMethodArgumentResolver}.
*/
public HandlerMethodArgumentResolverComposite addResolver(HandlerMethodArgumentResolver resolver) {
this.argumentResolvers.add(resolver);
return this;
}
/**
* Add the given {@link HandlerMethodArgumentResolver}s.
* @since 4.3
*/
public HandlerMethodArgumentResolverComposite addResolvers(@Nullable HandlerMethodArgumentResolver... resolvers) {
if (resolvers != null) {
for (HandlerMethodArgumentResolver resolver : resolvers) {
this.argumentResolvers.add(resolver);
}
}
return this;
}
/**
* Add the given {@link HandlerMethodArgumentResolver}s.
*/
public HandlerMethodArgumentResolverComposite addResolvers(
@Nullable List<? extends HandlerMethodArgumentResolver> resolvers) {
if (resolvers != null) {
for (HandlerMethodArgumentResolver resolver : resolvers) {
this.argumentResolvers.add(resolver);
}
}
return this;
}
/**
* Return a read-only list with the contained resolvers, or an empty list.
*/
public List<HandlerMethodArgumentResolver> getResolvers() {
return Collections.unmodifiableList(this.argumentResolvers);
}
/**
* Clear the list of configured resolvers.
* @since 4.3
*/
public void clear() {
this.argumentResolvers.clear();
}
/**
* Whether the given {@linkplain MethodParameter method parameter} is supported by any registered
* {@link HandlerMethodArgumentResolver}.
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
return (getArgumentResolver(parameter) != null);
}
/**
* Iterate over registered {@link HandlerMethodArgumentResolver}s and invoke the one that supports it.
* @throws IllegalStateException if no suitable {@link HandlerMethodArgumentResolver} is found.
*/
@Override
@Nullable
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
if (resolver == null) {
throw new IllegalArgumentException("Unknown parameter type [" + parameter.getParameterType().getName() + "]");
}
return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
}
/**
* Find a registered {@link HandlerMethodArgumentResolver} that supports the given method parameter.
*/
@Nullable
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
if (result == null) {
for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {
if (logger.isTraceEnabled()) {
logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" +
parameter.getGenericParameterType() + "]");
}
if (methodArgumentResolver.supportsParameter(parameter)) {
result = methodArgumentResolver;
this.argumentResolverCache.put(parameter, result);
break;
}
}
}
return result;
}
}
RequestResponseBodyMethodProcessor
@RequestBody和@ResponseBody处理
//最上层实现了HandlerMethodArgumentResolver,是用来处理@RequestBody类的请求
//supportsReturnType和handleReturnValue是处理返回值的
public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor {
/**
* Basic constructor with converters only. Suitable for resolving
* {@code @RequestBody}. For handling {@code @ResponseBody} consider also
* providing a {@code ContentNegotiationManager}.
*/
public RequestResponseBodyMethodProcessor(List<HttpMessageConverter<?>> converters) {
super(converters);
}
/**
* Basic constructor with converters and {@code ContentNegotiationManager}.
* Suitable for resolving {@code @RequestBody} and handling
* {@code @ResponseBody} without {@code Request~} or
* {@code ResponseBodyAdvice}.
*/
public RequestResponseBodyMethodProcessor(List<HttpMessageConverter<?>> converters,
@Nullable ContentNegotiationManager manager) {
super(converters, manager);
}
/**
* Complete constructor for resolving {@code @RequestBody} method arguments.
* For handling {@code @ResponseBody} consider also providing a
* {@code ContentNegotiationManager}.
* @since 4.2
*/
public RequestResponseBodyMethodProcessor(List<HttpMessageConverter<?>> converters,
@Nullable List<Object> requestResponseBodyAdvice) {
super(converters, null, requestResponseBodyAdvice);
}
/**
* Complete constructor for resolving {@code @RequestBody} and handling
* {@code @ResponseBody}.
*/
public RequestResponseBodyMethodProcessor(List<HttpMessageConverter<?>> converters,
@Nullable ContentNegotiationManager manager, @Nullable List<Object> requestResponseBodyAdvice) {
super(converters, manager, requestResponseBodyAdvice);
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(RequestBody.class);
}
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) ||
returnType.hasMethodAnnotation(ResponseBody.class));
}
/**
* Throws MethodArgumentNotValidException if validation fails.
* @throws HttpMessageNotReadableException if {@link RequestBody#required()}
* is {@code true} and there is no body content or if there is no suitable
* converter to read the content with.
*/
@Override
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
parameter = parameter.nestedIfOptional();
Object arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType());
String name = Conventions.getVariableNameForParameter(parameter);
if (binderFactory != null) {
WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name);
if (arg != null) {
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
}
}
if (mavContainer != null) {
mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());
}
}
return adaptArgumentIfNecessary(arg, parameter);
}
@Override
protected <T> Object readWithMessageConverters(NativeWebRequest webRequest, MethodParameter parameter,
Type paramType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
Assert.state(servletRequest != null, "No HttpServletRequest");
ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest);
Object arg = readWithMessageConverters(inputMessage, parameter, paramType);
if (arg == null && checkRequired(parameter)) {
throw new HttpMessageNotReadableException("Required request body is missing: " +
parameter.getExecutable().toGenericString());
}
return arg;
}
protected boolean checkRequired(MethodParameter parameter) {
RequestBody requestBody = parameter.getParameterAnnotation(RequestBody.class);
return (requestBody != null && requestBody.required() && !parameter.isOptional());
}
@Override
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
mavContainer.setRequestHandled(true);
ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);
//写回数据,java对象-> Json对象 -> 返回客户端
// Try even with null return value. ResponseBodyAdvice could get involved.
writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
}
}
分析SpringMVC运行流程
//model
@Data
public class User{
private String firstName;
private String lastName;
}
@RestCotroller
@RequestMapping(value ="/user",method = RequestMethod.GET)
public class UserController{
@GetMapping("/info/{firstName}/{lastName}")
public User getUser(@PathVariable("firstName") String firstName,
@PathVariable("lastName") String lastName){
User user = new User(firstName,lastName);
System.out.println(user);
return user;
}
}
- 如果把getUser的方法设置为private也是可以的,使用的springMvc的反射
源码分析
- User user = new User(firstName,lastName); 处打断点
- HttpServlet的继承类-> FrameworkServlet的doGet方法 -> processRequest(..)
- -> doService(..)抽象类使用了模板方法 -> 子类DispatcherServlet的doService(..)方法
- -> doDispatch(..)处理handlerMapping和handlerAdapter的方法
详解doDispatch(..)