Spring中可复用工具类&&特性记录&&技巧

Spring 里有用工具类:

GenericTypeResolver 解析泛型类型。核心逻辑还是调用 ResolvableType
ResolvableType 解析泛型类型参数

 1 interface Service2<N, M> {}
 2 
 3 class ABService2 implements Service2<A, B> {}
 4 class A {}
 5 class B{}
 6 
 7 
 8 public class TestGenericClass2 {
 9 
10     public static void main(String[] args) {
11         /** JDK 原生的方法获取泛型参数 **/
12         //获取ABService2实现的第一个接口,即Service2<A, B>
13         ParameterizedType parameterizedType = (ParameterizedType) ABService2.class.getGenericInterfaces()[0];
14         System.out.println(parameterizedType);
15         //从Service2<A, B> 获得第1个泛型参数,即A
16         Type genericType = parameterizedType.getActualTypeArguments()[0];
17         System.out.println(genericType);
18         System.out.println("*************");
19         
20         /** 通过 Spring API 获取泛型参数 **/
21         ResolvableType resolvableType = ResolvableType.forClass(ABService2.class);
22         // 以下两种方式都可以获取到泛型参数 A
23         // 指定类来获取
24         Class c=resolvableType.as(Service2.class).getGeneric(0).resolve();
25         Class d=resolvableType.getInterfaces()[0].getGeneric(0).resolve();
26         System.out.println("c   "+c);
27         System.out.println("d   "+d);
28         System.out.println("__________");
29 
30         //下面的可以获得被aop代理之前的类型
31 //        ClassUtils.getUserClass(myClass);
32     }
33 }
View Code

 


BeanWrapper 利用反射修改 JavaBean 的属性值。(支持修改嵌套属性)

  dubbo 中的 com.alibaba.dubbo.common.bytecode.Wrapper 实现了类似的功能
public class Foo {
    private int id;
    private String name;
    ......
}



public static void main(String[] args) {
    Foo foo = new Foo();
    
    // org.springframework.beans.BeanWrapper给对象属性赋值
    BeanWrapper bw = new BeanWrapperImpl(foo);
    bw.setPropertyValue("id", 123); // 给 Foo的id属性赋值
    
    // com.alibaba.dubbo.common.bytecode.Wrapper给对象属性赋值
    Wrapper.getWrapper(Foo.class).setPropertyValue(foo, "id", 123); // 给 Foo的id属性赋值
    System.out.println(JSON.toJSONString(foo));
}
View Code

 

IntrospectionSupport 设置 JavaBean 属性。 IntrospectionSupport.setProperties(Object target, Map<String, ?> props, String optionPrefix)

 

org.springframework.core.Constants : 处理 public static final 字段


org.springframework.util.ReflectionUtils :反射相关
org.springframework.util.ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);

ReflectionUtils.doWithFields()
ReflectionUtils.doWithMethods()

 

取属性值:

@Autowired
private Environment env;  
env.getProperty("spring.redis.pool.max-idle")

获取资源文件:

ResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver();
Resource[] source = resourceLoader.getResources(filePath); // 支持ant风格的路径匹配(?、*、**)

 

流处理:

org.springframework.util.StreamUtils  (流拷贝、从流中读取数据.....)

 

通用常量:

org.springframework.http.MediaType
如:APPLICATION_JSON_UTF8_VALUE --> application/json;charset=UTF-8

org.springframework.http.HttpStatus
如:OK(200, "OK")

 

Junit自动回滚:

@Test
@Rollback
@Transactional
public void testRollback(){
    xxxService.insert(instance);
}

 

-----------------------------------------------------技巧----------------------------------------------------

1. 找一个带命名空间(namespace)配置的处理类,可以从 NamespaceHandler 接口入手,找实现类

例如: <context:component-scan base-package="com.kvn.xx" />
可以从 NamespaceHandler 的实现类中找到 ContextNamespaceHandler

public class ContextNamespaceHandler extends NamespaceHandlerSupport {
    @Override
    public void init() {
        registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
        registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
        registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
        registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
        registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
        registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
        registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
        registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
    }
}
View Code

然后就能找到 component-scan 的处理类为: ComponentScanBeanDefinitionParser

 

2. springMvc 使用时,如果代码有进行地址重定向(sendRedirect),可以从下面步骤入手(判断是否服务器重定向&&相应的 Controller)

断点打在 DispatcherServlet#doDispatch() ,观察 request 和 response 

查看图片

 

3. 属性映射 org.springframework.boot.context.properties.PropertyMapper

工具类,可用于将值从提供源(supplied source)映射到目标。
主要用于将@ConfigurationProperties的值映射到第三方类时提供帮助。
可以通过谓词进行筛选:

PropertyMapper map = PropertyMapper.get();
   map.from(source::getName)
     .to(destination::setName);
   map.from(source::getTimeout)
     .whenNonNull()
     .asInt(Duration::getSeconds)
     .to(destination::setTimeoutSecs);
   map.from(source::isEnabled)
     .whenFalse().
     .toCall(destination::disable);

实例:
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryCustomizer#customize

 

posted on 2017-10-19 16:13  快鸟  阅读(759)  评论(0)    收藏  举报