avatar

目录
spring-自定义注解

spring自定义注解

spring 自定义注解用处很多,可以用来验证权限,也可以自定义功能

1.常用注解

对于@component 注解,怎么添加到spring 容器中的。

查看Spring的源码会发现,Spring是使用*ClassPathScanningCandidateComponentProvider*扫描package,

这个类通过扫basePackage的 classpath , 会判断被@Component 标注的类加入 inCludeFilter中 被spring扫描到加入容器,

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class) cl.loadClass("javax.annotation.ManagedBean")), false));
logger.info("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class) cl.loadClass("javax.inject.Named")), false));
logger.info("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}

2.定制注解

(1)还是使用以上的方法,然后再去出来进行处理,比如 spring MVC 的@controller,就是这么实现的。

** 那么Spring MVC是如何获取这些映射关系,并将其注册到handlerMap中呢?**

   取出所有bean ,循环查找Controller的bean 取出RequestMapping的信息,并将URL与Controller的映射关系注册到handlerMap中。

(实例:*AbstractDetectingUrlHandlerMapping* 中的 *detectHandlers*方法,这个方法的目的是取得所有可能的Controller,并将URL与Controller的映射关系注册到handlerMap中,默认实现类 DefaultAnnotationHandlerMapping )

(这个方法 取出所有object的bean 然后进行筛选,[基于注解的Spring MVC的URL与Controller映射关系提取的实现分析](http://blog.csdn.net/gavid0124/article/details/45247777),)
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
protected void detectHandlers() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Looking for URL mappings in application context: " + getApplicationContext());
}
String[] beanNames = (this.detectHandlersInAncestorContexts ?
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
getApplicationContext().getBeanNamesForType(Object.class));

// Take any bean name that we can determine URLs for.
for (String beanName : beanNames) {
String[] urls = determineUrlsForHandler(beanName);
if (!ObjectUtils.isEmpty(urls)) {
// URL paths found: Let's consider it a handler.
registerHandler(urls, beanName);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Rejected bean name '" + beanName + "': no URL paths identified");
}
}
}
}
Code
1
2
3
4
5
6
7
protected String[] determineUrlsForHandler(String beanName) {
ApplicationContext context = getApplicationContext();
Class handlerType = context.getType(beanName);
RequestMapping mapping = context.findAnnotationOnBean(beanName, RequestMapping.class);
if (mapping != null) {
// @RequestMapping found at type level
this.cachedMappings.put(handlerType, mapping);

(2)不依赖@component 扫描,自定义扫描,需要用到spring 对外提供的几种接口

ApplicationContextAware接口:spring 读取实现这个接口的类通过setApplicationContext 方法 传入spring的applicationContext

BeanFactoryPostProcessor接口:Spring会在BeanFactory的相关处理完成后调用postProcessBeanFactory方法,进行定制的功能。

3.对于定制的注解 可以使用spring提供的方法进行扫描

Code
1
2
3
4
5





参考文章:

http://www.jianshu.com/p/7c2948f64b1c

http://blog.csdn.net/gavid0124/article/details/45247777

java 注解

1、@Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括:
ElemenetType.CONSTRUCTOR 构造器声明
ElemenetType.FIELD 域声明(包括 enum 实例)
ElemenetType.LOCAL_VARIABLE 局部变量声明
ElemenetType.METHOD 方法声明
ElemenetType.PACKAGE 包声明
ElemenetType.PARAMETER 参数声明
ElemenetType.TYPE 类,接口(包括注解类型)或enum声明
2、@Retention 表示在什么级别保存该注解信息。可选的 RetentionPolicy 参数包括:
RetentionPolicy.SOURCE 注解将被编译器丢弃
RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃
RetentionPolicy.RUNTIME VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。

**  @Inherited **比如有一个类A,在他上面有一个标记annotation,那么A的子类B是否不用再次标记annotation就可以继承得到呢,答案是肯定的

Code
1
2
3
4
5
6
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DappRequestBody {

}

//自定义注解相关设置
@Documented
@Target``({ ElementType.METHOD, ElementType.TYPE })
@Retention``(RetentionPolicy.RUNTIME)
public @interface Authority {
``Role[]value() ``default { Role.USER };
``//自定义注解的属性,default是设置默认值
``// String desc() default "无描述信息";
}

文章作者: 美式不加糖
文章链接: http://yoursite.com/2020/02/04/spring-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B3%A8%E8%A7%A3/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 湖畔小屋
打赏
  • 微信
    微信
  • 支付寶
    支付寶