spring 自定义注释怎么获取package.json 注释 中 class 文件中 带我自定义的注释 的类名

Can anyone explain what I need to do to implement my own annotation that would add functionality to my web requests?
For example:
@Controller public class MyController {
@RequestMapping("/abc")
@RequiresSomeSpecialHandling
public void handleSecureRequest() {
Here @RequiresSomeSpecialHandling would be my own annotation that causes some special work to be done before or after the given web request /abc.
I know that on a very high level I would need to write a bean post processor, scan classes for my annotations, and inject custom mvc interceptors when needed. But are there any shortcuts to simplify this task? Especially for the two examples above.
Thanks in advance,
Can anyone explain what I need to do to implement my own annotation that would add functionality to my web requests?
For example:
@Controller public class MyController {
@RequestMapping("/abc")
@RequiresSomeSpecialHandling
public void handleSecureRequest() {
Here @RequiresSomeSpecialHandling would be my own annotation that causes some special work to be done before or after the given web request /abc.
I know that on a very high level I would need to write a bean post processor, scan classes for my annotations, and inject custom mvc interceptors when needed. But are there any shortcuts to simplify this task? Especially for the two examples above.
Thanks in advance,
不错,不错!
拦截器实现方式覆盖preHandle方法
public boolean preHandle(HttpServletRequest request, &&
& & & & & & HttpServletResponse response, Object handler) throws Exception {
& & Method m = AnnotationMethodHandlerAdapter.class.getDeclaredMethod("getMethodResolver", Object.class);
& & m.setAccessible(true);
& & HandlerMethodResolver resolver = (HandlerMethodResolver)m.invoke(annotationMethodHandlerAdapter, handler);
& & Method resolveHandlerMethod = resolver.getClass().getMethod("resolveHandlerMethod", HttpServletRequest.class);
& & resolveHandlerMethod.setAccessible(true);
& & Method currentMethod = (Method)resolveHandlerMethod.invoke(resolver, request);
& & AccessPermission AccessPermission = currentMethod.getAnnotation(AccessPermission.class);
& & System.out.println(currentMethod.getName() + "="+AccessPermission);
&&&&&&&&&&&&& & //获取到自定义注解AccessPermission,处理后续逻辑
}catch(Exception e){
e.printStackTrace();
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DuplicateSubmitToken {
boolean bindToken()
boolean unbindToken()
package com.auspiciousclouds.support.spring.mvc.
import java.lang.reflect.M
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
import org.springframework.beans.BeansE
import org.springframework.context.ApplicationC
import org.springframework.context.ApplicationContextA
import org.springframework.web.bind.annotation.support.HandlerMethodR
import org.springframework.web.servlet.ModelAndV
import org.springframework.web.servlet.handler.HandlerInterceptorA
import com.auspiciousclouds.config.C
import com.auspiciousclouds.kit.UUIDK
import com.auspiciousclouds.model.domain.UserD
import com.auspiciousclouds.support.spring.mvc.annotation.DuplicateSubmitT
public class DuplicateSubmitTokenInterceptor
extends HandlerInterceptorAdapter implements ApplicationContextAware{
ApplicationContext applicationC
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
UserDomain sessionUser = UserDomain.get( request);
if (sessionUser != null) {
Method method = org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.class.getDeclaredMethod("getMethodResolver", Object.class);
method.setAccessible(true);
HandlerMethodResolver resolver = (HandlerMethodResolver)method.invoke(applicationContext.getBean("annotationMethodHandlerAdapter"), handler);
Method resolveHandlerMethod = resolver.getClass().getMethod("resolveHandlerMethod", HttpServletRequest.class);
resolveHandlerMethod.setAccessible(true);
Method executorMethod = (Method)resolveHandlerMethod.invoke(resolver, request);
DuplicateSubmitToken annotation = executorMethod.getAnnotation(DuplicateSubmitToken.class);
if (annotation != null) {
boolean bindSession = annotation.bindToken();
if (bindSession) {
request.getSession(false).setAttribute(Configuration.SystemConstant.DUPLICATETOKEN, UUIDKit.getUUID());
boolean unbindSession = annotation.unbindToken();
if (unbindSession) {
if (isDuplicateSubmitToken(request)) {
System.out.println("--------------------------------------------------------------------------DuplicateSubmitTokenInterceptor-----------------------------------------------------------------------------");
request.getSession(false).removeAttribute(Configuration.SystemConstant.DUPLICATETOKEN);
* isDuplicateSubmitToken 判断是否是重复提交
* @param request
* @exception
private boolean isDuplicateSubmitToken(HttpServletRequest request) {
String serverToken = (String) request.getSession(false).getAttribute(Configuration.SystemConstant.DUPLICATETOKEN);
if (serverToken == null) {
String clinetToken = request.getParameter(Configuration.SystemConstant.DUPLICATETOKEN);
if (clinetToken == null) {
if (!serverToken.equals(clinetToken)) {
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
super.postHandle(request, response, handler, modelAndView);
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
super.afterCompletion(request, response, handler, ex);
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationC
@RequestMapping("/home")
@DuplicateSubmitToken
public String home(ModelMap model){}
&&您还没有登录,点击这里或之后才能回复!
更多文档 →
更多资讯 →I want to create custom annotation and put that annotation on method level using HttpServletRequest object. so far I did this:
Created annotation
@Target(value={ElementType.METHOD,ElementType.PARAMETER})
@Retention(value=RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface CheckSession{
boolean isAuthenticate()
created handler class
@Component
public class CheckSessionClass implements HandlerMethodReturnValueHandler,HandlerMethodArgumentResolver {
public Object resolveArgument(MethodParameter arg0,
ModelAndViewContainer arg1, NativeWebRequest arg2,
WebDataBinderFactory arg3) throws Exception {
("......MY ANNOTATION CALLEDD.....resolveArgument");
public boolean supportsParameter(MethodParameter arg0) {
("......MY ANNOTATION CALLEDD.....supportsParameter");
public void handleReturnValue(Object retutnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
annotation=returnType.getMethodAnnotation(CheckSession.class);
if(annotation.isAuthenticate()){
("......got request is aurhenticated..true");
("......got request is aurhenticated..false");
public boolean supportsReturnType(MethodParameter arg0) {
("......MY ANNOTAION CALLEDD.....supportsReturnType");
created a controller to invoke annotation like this.
@Controller
public class MyController
@RequestMapping(method={RequestMethod.GET, RequestMethod.POST})
@CheckSession(isAuthenticate=true)
public ResponseEntity&String& mymethod (HttpServletRequest request)
///my code here....
My applicationContext.xml file is configured as auto component scan , but still my annotations class is not getting called.can anyone let me know my mistake.
解决方案 You still have to configure the interceptor in your application context (in spite of the auto-scan):
&bean id="checkSession" class="CheckSessionClass"/&
&bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"&
&property name="defaultHandler"&
&ref bean="checkSession"/&
&/property&
本文地址: &
我要创建自定义的注释,并使用的HttpServletRequest 对象把那个标注方法上水平。到目前为止,我这样做:创建注释
@Target(值= {ElementType.METHOD,ElementType.PARAMETER})@Retention(值= RetentionPolicy.RUNTIME)@Documented@遗传@Mapping公共@interface CheckSession {
布尔isAuthenticate()默认为} 创建处理程序类
@Component公共类CheckSessionClass实现HandlerMethodReturnValueHandler,HandlerMethodArgumentResolver {
公共对象resolveArgument(MethodParameter为arg0,
ModelAndViewContainer ARG1,ARG2 NativeWebRequest,
WebDataBinderFactory ARG3)抛出异常{
(“......我注解CALLEDD ..... resolveArgument”);
公共布尔supportsParameter(MethodParameter为arg0){
(“......我注解CALLEDD ..... supportsParameter”);
公共无效handleReturnValue(对象retutnValue,MethodParameter的返回类型,
ModelAndViewContainer mavContainer,NativeWebRequest的WebRequest)抛出异常{
CheckSession注释;
注释= returnType.getMethodAnnotation(CheckSession.class);
如果(annotation.isAuthenticate()){(“......得到请求aurhenticated..true”);
(“......得到请求aurhenticated..false”);
公共布尔supportsReturnType(MethodParameter为arg0){
(“......我ANNOTAION CALLEDD ..... supportsReturnType”);
}} 创建了一个控制器来调用的注释是这样的。
@Controller公共类myController的{@RequestMapping(方法= {RequestMethod.GET,RequestMethod.POST})@CheckSession(isAuthenticate =真)
公共ResponseEntity<串GT;的MyMethod(HttpServletRequest的请求)
///我的code这里....
}} 我applicationContext.xml文件配置为汽车零部件扫描,但仍是我的注解类是没有得到任何人called.can让我知道我的错误。解决方案 您还必须配置在拦截你的应用环境(尽管自动扫描): <豆的id =“checkSession”级=“CheckSessionClass”/>< bean类=“org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping”>
<属性名=“DefaultHandler的”>
<参考豆=“checkSession”/>
< /性&< /豆>
本文地址: &
扫一扫关注官方微信编程语言/IT/网络/java(12)
1、支持通过Spring的xml配置文件来制定要获取注解类的包,如何获取配置文件的参数:
* 通过依赖注入获取配置文件中的属性值
* @param basePackages
public void setBasePackages(String... basePackages) {
this.basePackages = baseP
2、Spring的xml配置文件:
&bean class=&com.lvbey.service.ServiceBean& scope=&singleton&&
&!-- 自动扫描的包 --&
&property name=&basePackages&&
&value&com.xxxx.service&/value&
&value&com.wwww.service&/value&
&/property&
3、由于在某些情况下,我们不想把拥有@Service的某些类(少数部分)获取出来,我们可以加上一个自定义注解:@NotAutowired2Service
所以,我们需要自己写一个自定义的注解类:
* 在某个类上添加了该注解后,将不会自动注入到需要被获取的service中
* @author Lvbey
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface NotAutowired2Service {
好了,现在我们支持从配置文件获取指定的包,支持自定义注解了,说了这么多,直接上源代码:
package com.lvbey.
import java.util.HashM
import java.util.M
import javax.annotation.R
import org.
import org.springframework.beans.BeansE
import org.springframework.context.ApplicationC
import org.springframework.context.ApplicationContextA
import org.springframework.context.annotation.S
import com.lvbey.service.util.ClassU
* @author Lvbey
@Component //交给spring管理方便其他类获取该类对象
@Scope(value=&singleto&)//单例
public class ServiceBean implements ApplicationContextAware{
private ApplicationContext applicationC
* 获取到的类的实例对象
private Map&String, Object& classI
* 待扫描的基础包名
private String[] baseP
* 通过依赖注入获取配置文件中的属性值
* @param basePackages
public void setBasePackages(String... basePackages) {
this.basePackages = baseP
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationC
public void init(){
if(this.applicationContext == null){
if(this.classInstances == null){
this.classInstances = new HashMap&String,Object&();
//获取有NotAutowired2Service注解的实例
Map&String, Object& beansWithNotAutowired2ServiceMap = this.applicationContext.getBeansWithAnnotation(com.lvbey.service.annotation.NotAutowired2Service.class);
Map&String, Object& beansWithAnnotationMap = this.applicationContext.getBeansWithAnnotation(org.springframework.stereotype.Service.class);
Class&? extends Object& clazz =
for(Map.Entry&String, Object& entry : beansWithAnnotationMap.entrySet()){
clazz = entry.getValue().getClass();//获取到实例对象的class信息
Class&? extends Object&
[] interfaces = clazz.getInterfaces();
for(Class&? extends Object&
aInterface : interfaces){
String aInterfaceName = aInterface.getName();//接口的完整名
for(String packageName : this.basePackages){
if(aInterfaceName.startsWith(packageName)){//如果这个接口是在指定的包下
//接口实例名(只是将接口的首字母换成小写)
String aInterfaceSimpleName = ClassUtil.getDefaultInstanceName(aInterface);
//如果这个接口没有NotServiceBean注解
if(beansWithNotAutowired2ServiceMap.containsValue(entry.getValue())){
System.out.println(entry.getValue() + & has NotAutowired2Service Annotation&);
classInstances.put(aInterfaceSimpleName, entry.getValue());
public Map&String, Object& getClassInstances() {
if(this.classInstances == null){
return this.classI
里面用到了一个util工具类:
public class ClassUtil {
* 根据这个类来获取默认的实例名(默认:将首字母换成小写)
* @param clazz
* @return 默认的实例名
public static String getDefaultInstanceName(Class&?& clazz) {
if (clazz == null) {
String className = clazz.getSimpleName();
String firsrLowerChar = className.substring(0, 1).toLowerCase();
className = firsrLowerChar + className.substring(1);
return classN
然后怎么使用这个类呢?很简单,在你需要使用的那个类里面加上Spring的自动注入就行:
@Autowired
private ServiceBean serviceB
serviceBean.getClassInstances() ;//获取得到的map集合,剩下的想干啥干啥
对于不想写代码,想直接使用的看官。。。。。。轻戳
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:12092次
排名:千里之外
原创:11篇
(2)(2)(5)(1)(1)(7)Java注解教程:自定义注解示例,利用反射进行解析 - ImportNew
Java注解能够提供代码的相关信息,同时对于所注解的代码结构又没有直接影响。在这篇教程中,我们将学习Java注解,如何编写自定义注解,注解的使用,以及如何使用反射解析注解。
注解是Java 1.5引入的,目前已被广泛应用于各种Java框架,如Hibernate,,Spring。注解相当于是一种嵌入在程序中的元数据,可以使用注解解析工具或编译器对其进行解析,也可以指定注解在编译期或运行期有效。
在注解诞生之前,程序的元数据存在的形式仅限于java注释或javadoc,但注解可以提供更多功能,它不仅包含元数据,还能作用于运行期,注解解析器能够使用注解决定处理流程。举个例子,在中,我们在一个方法上添加了PATH注解和URI字符串,在运行期,jersey会对其进行解析,并决定作用于指定URI模式的方法。
在Java中创建自定义注解
创建自定义注解与编写接口很相似,除了它的接口关键字前有个@符号。我们可以在注解中定义方法,先来看个例子,之后我们会继续讨论它的特性。
package com.journaldev.
import java.lang.annotation.D
import java.lang.annotation.ElementT
import java.lang.annotation.I
import java.lang.annotation.R
import java.lang.annotation.RetentionP
import java.lang.annotation.T
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo{
String author() default &Pankaj&;
String date();
int revision() default 1;
String comments();
注解方法不能有参数。
注解方法的返回类型局限于原始类型,字符串,枚举,注解,或以上类型构成的数组。
注解方法可以包含默认值。
注解可以包含与其绑定的元注解,元注解为注解提供信息,有四种元注解类型:
1. @Documented – 表示使用该注解的元素应被javadoc或类似工具文档化,它应用于类型声明,类型声明的注解会影响客户端对注解元素的使用。如果一个类型声明添加了Documented注解,那么它的注解会成为被注解元素的公共API的一部分。
2. @Target – 表示支持注解的程序元素的种类,一些可能的值有TYPE, METHOD, CONSTRUCTOR, FIELD等等。如果Target元注解不存在,那么该注解就可以使用在任何程序元素之上。
3. @Inherited – 表示一个注解类型会被自动继承,如果用户在类声明的时候查询注解类型,同时类声明中也没有这个类型的注解,那么注解类型会自动查询该类的父类,这个过程将会不停地重复,直到该类型的注解被找到为止,或是到达类结构的顶层(Object)。
4. @Retention – 表示注解类型保留时间的长短,它接收RetentionPolicy参数,可能的值有SOURCE, CLASS, 以及RUNTIME。
Java内置注解
Java提供3种内置注解。
1. @Override – 当我们想要覆盖父类的一个方法时,需要使用该注解告知编译器我们正在覆盖一个方法。这样的话,当父类的方法被删除或修改了,编译器会提示错误信息。大家可以学习一下为什么我们总是应该在覆盖方法时使用。
2. @Deprecated – 当我们想要让编译器知道一个方法已经被弃用(deprecate)时,应该使用这个注解。Java推荐在javadoc中提供信息,告知用户为什么这个方法被弃用了,以及替代方法是什么。
3. @SuppressWarnings – 这个注解仅仅是告知编译器,忽略它们产生了特殊警告,比如:在中使用原始类型。它的保持性策略(retention policy)是SOURCE,在编译器中将被丢弃。
我们来看一个例子,展示了如何使用内置注解,以及上述示例中提及的自定义注解。
package com.journaldev.
import java.io.FileNotFoundE
import java.util.ArrayL
import java.util.L
public class AnnotationExample {
public static void main(String[] args) {
@MethodInfo(author = &Pankaj&, comments = &Main method&, date = &Nov 17 2012&, revision = 1)
public String toString() {
return &Overriden toString method&;
@Deprecated
@MethodInfo(comments = &deprecated method&, date = &Nov 17 2012&)
public static void oldMethod() {
System.out.println(&old method, don't use it.&);
@SuppressWarnings({ &unchecked&, &deprecation& })
@MethodInfo(author = &Pankaj&, comments = &Main method&, date = &Nov 17 2012&, revision = 10)
public static void genericsTest() throws FileNotFoundException {
List l = new ArrayList();
l.add(&abc&);
oldMethod();
我相信这个例子是很明了的,展示了不同场景下注解的使用方式。
Java注解解析
我们将使用Java反射机制从一个类中解析注解,请记住,注解保持性策略应该是RUNTIME,否则它的信息在运行期无效,我们也不能从中获取任何数据。
package com.journaldev.
import java.lang.annotation.A
import java.lang.reflect.M
public class AnnotationParsing {
public static void main(String[] args) {
for (Method method : AnnotationParsing.class
.getClassLoader()
.loadClass((&com.journaldev.annotations.AnnotationExample&))
.getMethods()) {
// checks if MethodInfo annotation is present for the method
if (method
.isAnnotationPresent(com.journaldev.annotations.MethodInfo.class)) {
// iterates all the annotations available in the method
for (Annotation anno : method.getDeclaredAnnotations()) {
System.out.println(&Annotation in Method '&
+ method + &' : & + anno);
MethodInfo methodAnno = method
.getAnnotation(MethodInfo.class);
if (methodAnno.revision() == 1) {
System.out.println(&Method with revision no 1 = &
+ method);
} catch (Throwable ex) {
ex.printStackTrace();
} catch (SecurityException | ClassNotFoundException e) {
e.printStackTrace();
以上程序的输出是:
Annotation in Method 'public java.lang.String com.journaldev.annotations.AnnotationExample.toString()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=Main method, date=Nov 17 2012)
Method with revision no 1 = public java.lang.String com.journaldev.annotations.AnnotationExample.toString()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @java.lang.Deprecated()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=deprecated method, date=Nov 17 2012)
Method with revision no 1 = public static void com.journaldev.annotations.AnnotationExample.oldMethod()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.genericsTest() throws java.io.FileNotFoundException' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=10, comments=Main method, date=Nov 17 2012)
注解API非常强大,被广泛应用于各种Java框架,如Spring,Hibernate,JUnit。可以查看《》获得更多信息。
这就是java注解教程的全部内容了,我希望你能从中学到一些东西。
原文链接:
- 译文链接: [ 转载请保留原文出处、译者和译文链接。]
关于作者:
(新浪微博:)
文中说:系统可被分为两个逻辑组件(这强大的理解和功力):1) Log层2) 服务层我的理解:Log层...
关于ImportNew
ImportNew 专注于 Java 技术分享。于日 11:11正式上线。是的,这是一个很特别的时刻 :)
ImportNew 由两个 Java 关键字 import 和 new 组成,意指:Java 开发者学习新知识的网站。 import 可认为是学习和吸收, new 则可认为是新知识、新技术圈子和新朋友……
新浪微博:
推荐微信号
反馈建议:@
广告与商务合作QQ:
– 好的话题、有启发的回复、值得信赖的圈子
– 写了文章?看干货?去头条!
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 活跃 & 专业的翻译小组
– 国内外的精选博客文章
– UI,网页,交互和用户体验
– JavaScript, HTML5, CSS
– 专注Android技术分享
– 专注iOS技术分享
– 专注Java技术分享
– 专注Python技术分享
& 2017 ImportNew

我要回帖

更多关于 spring 自定义注释 的文章

 

随机推荐