Spring Cloud Gateway整合Spring Doc
Spring Cloud Gateway整合Spring Doc最近在新项目使用到了Spring Doc,支持open api 3.
依赖引入使用Spring Doc 1.6.14版本。
12345678910111213141516171819202122232425<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId></dependency><dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-webflux-ui</artifactId></dependency><dependency> <groupId>org.springdoc</groupId> ...
处理字典值反显问题.md
处理字典值反显问题项目中往往只保存了字典的key值,前端页面显示时需要展示字面值。
解决方案通常有以下几种:
前端展示时,根据字典key,调用专门的接口去查询字面值。为了性能考虑,可以将查询结果缓存到浏览器。适用于不常变化的字典值。
后端返回结果前将字典值处理好后一起返回。这里面也有几种处理方式:
查询时sql关联查询字典表。适用于字典模块与业务模块没有分离的情况。
返回结果根据字典值调用字典接口查询出字面值。适用于字典与业务分离的情况。字典接口可以根据情况做缓存。
这里简单说一下最后一种处理方式。
具体思路是利用mybatis的插件去处理每条记录中特定的字段。
定义标记注解FieldBind该注解用来某个字段上,用来标记该字段是字典值,需要反显。
1234567891011121314151617@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})@Inheritedpublic @interface FieldBind ...
Spring AOP 调用同一个对象的方法
经过前面的学习,我们了解了Spring AOP的执行过程。这里想提醒注意一个小问题,我们在对象的方法中调用该对象的另外一个方法会出现什么现象呢?
现象
定义对象方法
123456789101112131415public class BusinessService implements IBusinessService{ @Override public String sayHello(){ System.out.println("hello"); System.out.println("i want to say again"); this.sayAgain(); return "hello"; } @Override public String sayAgain() { System.out.println("again"); return " ...
Spring AOP基本用法3
前面讲到了使用XML 配置ProxyFactoryBean,结合注解配置@Bean也可以实现代码配置。还讲到了代码配置ProxyFactory。前者与Spring IOC 容器结合的更紧密,不需要自己调用getProxy()方法,从IOC 容器中获取的Bean 已经是最终的代理对象。
这两种方式需要我们自己设置目标对象,通知以及代理接口,使用起来还是比较繁琐的。每当我们需要一个代理对象时,就需要配置ProxyFactoryBean或ProxyFactory。
有没有更好的方式,只需要做简单的配置就可以为多个对象生成代理对象呢?
我们已经有了创建代理的方式,就是前面介绍的工厂类,剩下的工作只需要解决如何配置和如何解析配置的问题就可以了。
下面介绍最核心的类。
AbstractAutoProxyCreator看看Spring 官方介绍:
该抽象类实现了BeanPostProcessor接口,用AOP代理来包装每个合适的bean,并在调用bean本身之前委托给指定的拦截器。这个类区分了“公共”拦截器和“特定”拦截器,前者用于它创建的所有代理,后者用于每个bean实例。可以不需要任何通用的拦 ...
Spring AOP基本用法2
Spring AOP 用法二在上一篇中讲到通过xml配置ProxyFactoryBean来创建代理对象,在这一篇中看看通过编程的方式配置ProxyFactory。该类继承自ProxyCreatorSupport(之前提到过该类提供了一些创建代理对象的基础方法),提供了配置目标对象,代理接口和通知的功能。
基本用法123456789101112131415DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);xmlBeanDefinitionReader.loadBeanDefinitions("AopXmlSimpleConfig.xml");// 获取需求代理的目标对象IBusinessService bean = beanFactory.getBean("businessServi ...
Spring AOP基本用法
Spring AOP 用法前面讲到了AOP相关的思想和基本概念,实现方式可分为静态编绎型和代理两种方式。前者的代表作是AspectJ,在编绎阶段将通知织入到class中,需要用到特殊的工具来编绎。AspectJ定义了一种表达式语言来定义连接点,Spring 默认是基于JDK动态代理来实现AOP,并且只支持方法作为切入点。
如何使用Spring 自己实现了一套AOP,还部分支持AspectJ。两种方式都可以使用编程式和xml配置方式。
使用Spring AOP大概有以下几种方式:
在xml中配置ProxyFactoryBean,显式地设置advisors, advice, target等,或以编程方式使用ProxyFactory。Spring支持通过 jdk 动态代理和 cglib 来生成代理对象。前者只支持接口,后者可以支持类。还可以以编程形式配置AspectJProxyFactory, 该类基于apsectj语法来配置切面。
配置AutoProxyCreator,这种方式下,还是如以前一样使用定义的bean,但是从容器中获得的其实已经是代理对象
通过<aop:config&g ...
AOP的基本概念
任何技术的出现都是为了解决某类问题。
AOP是什么?AOP出现以前,代码逻辑都是从上到下编写。当我们需要在原有主逻辑不变的情况下,修改一些无关逻辑时,比如我们需要在每个方法中打印出入参,这时我们需要修改每个方法,然后加上打印日志的代码。这无疑是非常消耗精力的事情,而且这样的代码也不好维护,更不符合设计原则。
有没有更好的方式可以达成这样的目的?
我们可不可以在不修改原有逻辑的情况下将需要新增的代码插入到原有的代码中?
有的。我们可以创建原有对象的代理,将新增的代码写在代码对象的方法里,这样我们就可以不用修改原有对象的方法了。但是,方法这么多,难道我们要新增N 个代理对象吗?当然不是。我们有字节码工具,可以通过代码来为每个对象生成代理对象。
这样的局限性也很大。如果要在原有方法调用前插入日志需要新增代理对象,在调用后插入日志又要新增代理对象。随着需要插入的位置变多,我们就要创建更多的代理对象。
我们也可以通过在方法调用之间增加过滤器的方式,就像Servlet模式中的Filter一样。但是要给每个方法添加过滤器,显然不现实。
有没有一种更灵活的方式可以让我们控制插入的时机?
有。
AOP( ...
自定义Scope
Bean 的生命周期所谓生命周期,即是Bean何时创建,何时生存,何时销毁。也即Bean 存在的范围。更直白点儿就是Bean的作用范围,有点儿变量的意味。
Spring 内置了singleton、prototype两种Scope,Bean 默认为singleton,在Spring IOC 容器中,只会创建一个,并将其缓存起来。
prototype作用域部署的bean,每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)都会产生一个新的bean实例,相当与一个new的操作。对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构回调方法都将不会被调用(destory-method不会被调用),因为在注册为DisposableBean时将protot ...
ObjectFactory与BeanFactory的区别
ObjectFactory 与BeanFactory 的区别Spring 体系中有一些跟 Bean获取相关的接口,比如:ObjectFactory、BeanFactory 、FactoryBean、ObjectProvider等。有时候会让人不知道该使用哪一个。下面具体看一下区别。
BeanFactory该接口是整个Spring容器的顶层接口,定义了从容器中获取Bean的方法。当我们的应用需要从容器中获取Bean的时候用此接口。在这里我们可以将整个容器看成是一个黑盒,不需要关心它是如何获取的,我们只关心结果。
ObjectFactory此接口定义了一个简单工厂,是一个函数式接口,可以在调用时返回一个对象实例(可能是共享的或独立的)。
这个接口类似于FactoryBean,但是后者的实现类通常被定义为BeanFactory中的SPI实例,而该类的实现通常被作为API(通过注入)提供给其他bean。因此,getObject()方法具有不同的异常处理行为。
1234567891011@FunctionalInterfacepublic interface ObjectFactory<T ...
BeanWrapper
BeanWrapperBeanWrapper是什么Spring底层操作Java Bean的核心接口。
通常不直接使用该接口,而是通过BeanFactory或DataBinder。
提供分析和操作标准Java Bean的操作: 获取和设置属性值(单个或批量)、获取属性描述以及查询属性的可读性/可写性的能力。
此接口还支持嵌套属性,允许将子属性上的属性设置为无限深度。
BeanWrapper的extractOldValueForEditor默认值是false,可以避免调用 getter方法。将此选项设置为true,可以向自定义编辑器暴露当前属性值。
可以看出BeanWrapper是操作Java Bean 的强大利器。
类结构
BeanWrapper 继承自TypeConverter,PropertyEditorRegistry,PropertyAccessor, ConfigurablePropertyAccessor接口。从名称可以看出具备了类型转换,属性编辑器注册,属性访问及配置的功能。
使用方式接下来看看如何使用BeanWrapper来操作我们的Java Bean。
Spring给我 ...