Spring 注解

Spring注解主要分为两类: spring bean容器的注解,springmvc相关的注解
1、Java的注解
例如@Override

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}



@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}



@Retention用于提示注解被保留多长时间,有三种取值:
RetentionPolicy.SOURCE 保留在源码级别,被编译器抛弃(@Override就是此类); RetentionPolicy.CLASS被编译器保留在编译后的类文件级别,但是被虚拟机丢弃;
RetentionPolicy.RUNTIME保留至运行时,可以被反射读取。
@Target用于提示该注解使用的地方,取值有:
分别表示该注解可以被使用的地方:1)类,接口,注解,enum; 2)属性域;3)方法;4)参数;5)构造函数;6)局部变量;7)注解类型;8)包

还有一个经常使用的元注解 @Documented :表示注解是否能被 javadoc 处理并保留在文档中。

2 使用元注解来自定义注解和处理自定义注解

// 简单示例
/**
 * 不需要登录注解
 */
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NoLogin {
}


/**
 * 检查登录拦截器
 * 如不需要检查登录可在方法或者controller上加上@NoLogin
 */
public class CheckLoginInterceptor implements HandlerInterceptor {
    private static final Logger logger = Logger.getLogger(CheckLoginInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            logger.warn("当前操作handler不为HandlerMethod=" + handler.getClass().getName() + ",req="
                        + request.getQueryString());
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        String methodName = handlerMethod.getMethod().getName();
        // 判断是否需要检查登录
        NoLogin noLogin = handlerMethod.getMethod().getAnnotation(NoLogin.class);
        if (null != noLogin) {
            if (logger.isDebugEnabled()) {
                logger.debug("当前操作methodName=" + methodName + "不需要检查登录情况");
            }
            return true;
        }
        noLogin = handlerMethod.getMethod().getDeclaringClass().getAnnotation(NoLogin.class);
        if (null != noLogin) {
            if (logger.isDebugEnabled()) {
                logger.debug("当前操作methodName=" + methodName + "不需要检查登录情况");
            }
            return true;
        }
        if (null == request.getSession().getAttribute(CommonConstants.SESSION_KEY_USER)) {
            logger.warn("当前操作" + methodName + "用户未登录,ip=" + request.getRemoteAddr());
            response.getWriter().write(JsonConvertor.convertFailResult(ErrorCodeEnum.NOT_LOGIN).toString()); // 返回错误信息
            return false;
        }
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) throws Exception {
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                                Object handler, Exception ex) throws Exception {
    }
}

简单解释一下,自定义一个拦截器,首先使用反射来判断方法上是否被@NoLogin注解

 NoLogin noLogin = handlerMethod.getMethod().getAnnotation(NoLogin.class);

然后判断类是否被@NoLogin注解

noLogin = handlerMethod.getMethod().getDeclaringClass().getAnnotation(NoLogin.class);

如果被注解了,就返回true,如果没被注解,判断是否已经登录,没登录则返回错误信息。

3、spring的bean容器相关的注解

  1. @Autowired,其实就是autowire=byType,就是根据类型的自动注入以来,可以被使用在属性域,方法,构造函数上。
  2. @Qualifier 就是autowire=byName,当@Autowired注解判断多个bean类型相同时,就需要使用@Qualifier(“xxxBean”)来指定依赖的bean的id
  3. @Resource,用于属性域和方法上,就是byName类型的依赖注入,不带参数默认值类名首字母小写
  4. JSR-330标准javax.inject.*中的注解(@Inject, @Named, @Qualifier, @Provider, @Scope, @Singleton)。@Inject就相当于@Autowired, @Named 就相当于 @Qualifier, 另外 @Named 用在类上还有 @Component的功能。
  5. @Component, @Controller, @Service, @Repository, 这几个注解不同于上面的注解,上面的注解都是将被依赖的bean注入进入,而这几个注解的作用都是生产bean, 这些注解都是注解在类上,将类注解成spring的bean工厂中一个一个的bean。@Controller, @Service, @Repository基本就是语义更加细化的@Component。
  6. @PostConstruct 和 @PreDestroy 不是用于依赖注入,而是bean 的生命周期。类似于 init-method(InitializeingBean) destory-method(DisposableBean)

4、spring中注解的处理
spring中的注解的处理基本都是通过实现接口BeanPostProcessor来进行的

public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

后续在说

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值