1.Java自定义注解与Spring
Java注解作为程序元素(类、成员变量、成员方法等)的一种元数据信息,对程序本身的执行不会产生影响。通过自定义注解,可以给程序元素添加特殊的声明。
Spring作为构建企业级应用的平台,提供了丰富的功能。将Java的自定义注解与Spring结合,在特定场景下实现注解的解析、处理,可以降低应用的耦合度,提高程序的可扩展性。
2.应用场景
下面总结几种应用场景,仅说明大致思路(ps:并非所有场景都在项目中实践过)
2.1登陆、权限拦截
在web项目中,登陆拦截和权限拦截是一个老生常谈的功能。通过自定义登陆注解或权限注解,在自定义拦截器中解析注解,实现登陆和权限的拦截功能。
这种使用方式,配置简单,灵活度高,代码耦合度低。
2.2定时任务管理
在系统构建过程中,会有各种定时任务的需求,而定时任务的集中管理,可以更高效维护系统的运行。
通过Java注解官方文档RepeatingAnnotations章节中的自定义的定时任务注解,可以实现业务方法的定时任务声明。结合Spring的容器后处理器BeanPostProcessor(ps:Spring容器后处理器下篇再说),解析自定义注解。解析后的注解信息再使用QuartzAPI构建运行时定时任务,即可完成定时任务的运行时创建和集中管理。
这种方式能避免定义Quartz定时任务的配置,提高系统扩展性。
2.3多数据源路由的数据源指定
Spring提供的AbstractRoutingDataSource实现多数据源的动态路由,可应用在主从分离的架构下。通过对不同的方法指定不同的数据源,实现数据源的动态路由(例如:读方法走从库数据源,写方法走主库数据源)。而如何标识不同的方法对应的数据源类型,则可使用自定义注解实现。通过解析方法上声明的自定义注解对应的数据源类型,实现数据源的路由功能。
这种方式避免了对方法的模式匹配解析(例如:select开头、update开头等),声明更加灵活。
自定义注解
先看一个最简单的例子,在使用SpringWeb应用中的过程中,大家免不了会使用@Controller,@Service,@Repository等注解来定义JavaBean。那么怎么自己定义一个注解,Spring可以自动加载呢。所以就有了第一个例子。
@Target({ ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface MyComponent { String value() default ""; }
@Configuration public class ComponentAnnotationTest { public static void main(String[] args) { AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(); annotationConfigApplicationContext.register(ComponentAnnotationTest.class); annotationConfigApplicationContext.refresh(); InjectClass injectClass = annotationConfigApplicationContext.getBean(InjectClass.class); injectClass.print(); } @MyComponent public static class InjectClass { public void print() { System.out.println("hello world"); } } }
运行这个例子,就会发现,@MyComponent 注解的类,也被Spring加载进来了,而且可以当成普通的JavaBean正常的使用。查看Spring的源码会发现,Spring是使用ClassPathScanningCandidateComponentProvider扫描package,这个类有这样的注释
A component provider that scans the classpath from a base package. It then applies exclude and include filters to the resulting classes to find candidates.
这个类的 registerDefaultFilters 方法有这样几行代码
protected void registerDefaultFilters() { this.includeFilters.add(new AnnotationTypeFilter(Component.class)); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false)); logger.debug("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<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false)); logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning"); } catch (ClassNotFoundException ex) { // JSR-330 API not available - simply skip. } }
这里就会发现Spring在扫描类信息的使用只会判断被@Component注解的类,所以任何自定义的注解只要带上@Component(当然还要有String value() default "";的方法,因为Spring的Bean都是有beanName唯一标示的),都可以被Spring扫描到,并注入容器内。
总结
以上就是本文关于浅谈自定义注解在Spring中的应用的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!
本文向大家介绍浅谈Spring中@Import注解的作用和使用,包括了浅谈Spring中@Import注解的作用和使用的使用技巧和注意事项,需要的朋友参考一下 @Import用来导入@Configuration注解的配置类、声明@Bean注解的bean方法、导入ImportSelector的实现类或导入ImportBeanDefinitionRegistrar的实现类。 @Import注解的作用
主要内容:运行项目根据切入点表达式可能会将它们应用到其他不需要通知的其他。 例如,考虑以下表达式: 如果一个新的spring bean添加了方法,并且通知将开始应用到它,尽管它可能不需要应用通知。要实现不需要它,我们可以创建一个自定义注解并注解要应用到通知的方法。 要了解上面提到的关于的概念,现在我们来写一个实现的例子。打开并使用Eclipse IDE,并按照以下步骤创建一个Spring应用程序: 更新在Sprin
主要内容:1.Aop的一些常用术语,2.通知类型,3.Spring AOP配置有两种风格:,4.案例1,5.案例21.Aop的一些常用术语 切面(Aspect):在Spring AOP中,切面可以使用通用类或者在普通类中以@Aspect 注解(@AspectJ风格)来实现 连接点(Joinpoint):在Spring AOP中一个连接点代表一个方法的执行 通知(Advice):在切面的某个特定的连接点(Joinpoint)上执行的动作。通知有各种类型,其中包括"around"、"before”和
主要内容:1.Aop的一些常用术语,2.通知类型,3.Spring AOP配置有两种风格:,4.案例1,5.案例21.Aop的一些常用术语 切面(Aspect):在Spring AOP中,切面可以使用通用类或者在普通类中以@Aspect 注解(@AspectJ风格)来实现 连接点(Joinpoint):在Spring AOP中一个连接点代表一个方法的执行 通知(Advice):在切面的某个特定的连接点(Joinpoint)上执行的动作。通知有各种类型,其中包括"around"、"before”和
本文向大家介绍浅谈ASP.NET中最简单的自定义控件,包括了浅谈ASP.NET中最简单的自定义控件的使用技巧和注意事项,需要的朋友参考一下 ASP.NET用户控件一般适用于产生相对静态的内容,所以没有builtin的事件支持。本文讨论用户控件返回事件的方法。 假定用户控件(UserControl.ascx)中包含按钮控件AButton,希望实现按AButton按钮时,包含该用户控件的页面可以接收
本文向大家介绍浅谈php自定义错误日志,包括了浅谈php自定义错误日志的使用技巧和注意事项,需要的朋友参考一下 平时经常看php的错误日志,很少有机会去自己动手写日志,看了王健的《最佳日志实践》觉得写一个清晰明了,结构分明的日志还是非常有必要的。 在写日志前,我们问问自己:为什么我们有时要记录自定义的日志呢?而不用系统默认的日志记录方式呢? 我认为有两个原因: 1.团队需要一个统一格式的日志方便管