java----注解
Annotation:
注解:
作用1:当对程序做解释的时候和注释的意义差不多
作用2:可以在编译期读取注解中的信息然后为程序所利用。
注释作用1
public class Test{
//可以起到一个提示的作用
@Override
public String toString() {
return super.toString();
}
}
系统自带注解
public class Demo{
public static void main(String[] args) {
Test test = new Test();
test.test(); //使用了不推荐使用的方法
}
}
//忽略编译期不当的警告
@SuppressWarnings("all")
class Test{
//表示这个方法不再建议使用;
@Deprecated
public void test(){
System.out.println("方法已经过时");
}
//检查此方法是不是覆盖了父类的方法
@Override
public String toString() {
return super.toString();
}
}
前言:注解的解析完全依赖于反射。
自定义注解,一个简单的例子
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
public class Demo{
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Class<Cat> catClass = Cat.class;
//获取类中应用的指定的注解
MyAnnotation annotation = catClass.getAnnotation(MyAnnotation.class);
//通过反射获取注解中的值
String name = annotation.name();
int age = annotation.age();
String[] like = annotation.like();
Color color = annotation.color();
//实例化对象
Cat cat = catClass.newInstance();
cat.setAge(age);
cat.setColor(color);
cat.setLike(like);
cat.setName(name);
System.out.println(cat);
}
}
enum Color{
red,black;
}
//表示注解再运行时依然存在
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
public String name();
public int age() default 10; //给变量设置默认值
public String[] like(); //定义一个数组变量
public Color color(); //定义一个枚举变量
}
@MyAnnotation(name="bin",like = {"鱼",},color = Color.black)
class Cat{
private String name;
private String[] like;
private Color color;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getLike() {
return like;
}
public void setLike(String[] like) {
this.like = like;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", like=" + Arrays.toString(like) +
", color=" + color +
", age=" + age +
'}';
}
}
注解详细解释
注解我们可以定义在类上,成员变量上等等
@TestA //使用了类注解
public class UserAnnotation {
@TestA //使用了类成员注解
private Integer age;
@TestA //使用了构造方法注解
public UserAnnotation(){
}
@TestA //使用了类方法注解
public void a(){
@TestA //使用了局部变量注解
Map m = new HashMap(0);
}
public void b(@TestA Integer a){ //使用了方法参数注解
}
}
四个元注解
@Target 表示该注解用于什么地方,可能的值在枚举类 ElemenetType 中,包括:
ElemenetType.CONSTRUCTOR----------------------------构造器声明
ElemenetType.FIELD --------------------------------------域声明(包括 enum 实例)
ElemenetType.LOCAL_VARIABLE------------------------- 局部变量声明
ElemenetType.METHOD ----------------------------------方法声明
ElemenetType.PACKAGE --------------------------------- 包声明
ElemenetType.PARAMETER ------------------------------参数声明
ElemenetType.TYPE--------------------------------------- 类,接口(包括注解类型)或enum声明
@Retention 表示在什么级别保存该注解信息。可选的参数值在枚举类型 RetentionPolicy 中,包括:
RetentionPolicy.SOURCE ---------------------------------注解将被编译器丢弃
RetentionPolicy.CLASS -----------------------------------注解在class文件中可用,但会被JVM丢弃
RetentionPolicy.RUNTIME VM-------将在运行期也保留注释,因此可以通过反射机制读取注解的信息。
@Documented 将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同。相当与@see,@param 等。
@Inherited 允许子类继承父类中的注解。
方法
#判断方法或者类是否有这个注解 xx.isAnnotationPresent(X.class) #isAssignableFrom()方法是判断是否为某个类的父类,instanceof关键字是判断是否某个类的子类。 父类.class.isAssignableFrom(子类.class) 子类实例 instanceof 父类类型
示例
import org.junit.Test;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import static java.lang.annotation.ElementType.*;
@Target({TYPE, METHOD, FIELD, CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
@interface TestA {
String name();
int id() default 0;
Class gid();
}
@TestA(id = 1, name = "type", gid = Long.class) //类注解
class UserAnnotation {
@TestA(name = "param", id = 2, gid = Long.class) //类成员注解
private Integer age;
@TestA(name = "construct", id = 3, gid = Long.class)//构造方法注解
public UserAnnotation() {
}
@TestA(name = "public method", id = 4, gid = Long.class) //类方法注解
public void a() {
}
@TestA(name = "protected method", id = 5, gid = Long.class) //类方法注解
protected void b() {
}
@TestA(name = "private method", id = 6, gid = Long.class) //类方法注解
private void c() {
}
public void b(Integer a) {
}
}
public class SpringbootProjectApplicationTests {
@Test
public void test() throws ClassNotFoundException, NoSuchMethodException {
Class<UserAnnotation> userAnnotationClass = UserAnnotation.class;
//获取类上注解的信息
Annotation[] annotations = userAnnotationClass.getAnnotations();
for (Annotation annotation : annotations) {
TestA testA = (TestA) annotation;
//打印了类注解的信息
System.out.println(testA.id() + "--" + testA.name() + "-" + testA.gid());
}
//获取所有声明的方法的注解信息(不包含构造方法)
Method[] declaredMethods = userAnnotationClass.getDeclaredMethods();
for (Method method:declaredMethods){
boolean annotationPresent = method.isAnnotationPresent(TestA.class);
if (annotationPresent){
TestA testA = method.getAnnotation(TestA.class);
System.out.println(testA.id() + "--" + testA.name() + "-" + testA.gid());
}
}
//获取指定的声明的方法的注解信息(不包含构造方法),获取字段的方式和方法类似getDeclareField("xx");
Method b = userAnnotationClass.getDeclaredMethod("b");
System.out.println(b.getAnnotation(TestA.class).id());
//获取所有构造方法的注解信息(指定的构造方法同理)
Constructor<?>[] constructors = userAnnotationClass.getConstructors();
for (Constructor constructor:constructors){
boolean annotationPresent = constructor.isAnnotationPresent(TestA.class);
if (annotationPresent){
TestA testA = (TestA) constructor.getAnnotation(TestA.class);
System.out.println(testA.id() + "--" + testA.name() + "-" + testA.gid());
}
}
}
}
使用注解完成类和表结构的映射关系(ORM)
使用注解进行数据表的创建
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TestTable{
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface TestUser{
public String columnName();
public String type();
public int len();
}
@TestTable("table")
public class Test{
@TestUser(columnName="id",type = "int",len = 10)
private int id;
@TestUser(columnName="username",type = "String",len = 32)
private String username;
@TestUser(columnName="password",type = "String",len = 32)
private String password;
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class<?> aClass = Class.forName("com.zy.Test");
Field username = aClass.getDeclaredField("username");
TestUser annotation = username.getAnnotation(TestUser.class);
System.out.println("字段:"+annotation.columnName());
System.out.println("属性:"+annotation.type());
System.out.println("长度:"+annotation.len());
//字段:username
//属性:String
//长度:32
//可以向这样获取所有的数据,拼接sql语句来创建数据表;
}
}
通过注解进行拦截
1、创建注解
import java.lang.annotation.*;
/***
* @Target 注解修饰类型
* @Retention 生命周期
* @Documented注解标记的元素,Javadoc工具会将此注解标记元素的注解信息包含在javadoc中
*/
@Target(value = {ElementType.METHOD,ElementType.TYPE,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LoginUser {
/**
* 用户角色及默认值
* @return
*/
String role() default "admin";
2、重写拦截组件,拦截逻辑
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@Component
public class LoginUserInterceptor extends HandlerInterceptorAdapter {
private static final Logger logger = LoggerFactory.getLogger(LoginUserInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
//注解在方法上的获取方法
LoginUser loginUserAnnotation = ((HandlerMethod) handler).getMethodAnnotation(LoginUser.class);
//注解在类上的获取方法
LoginUser classLoginUserAnnotation = ((HandlerMethod) handler).getMethod().getDeclaringClass().getAnnotation(LoginUser.class);
if (ObjectUtils.anyNotNull(loginUserAnnotation, classLoginUserAnnotation)) {
HttpSession session = request.getSession(false);
//获取注解使用过程中的值
System.out.println("pppppppppppppppppppppppppppppppppppppppppppppp"+loginUserAnnotation.role());
}
}
return true;
}
}
3.设置拦截规则
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@SpringBootConfiguration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Resource
private LoginUserInterceptor loginUserInterceptor;
/**
* addInterceptor()的顺序需要严格按照程序的执行的顺序
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// "/**" 拦截路径及其子路径
registry.addInterceptor(loginUserInterceptor).addPathPatterns("/**");
// "/*" 不拦截子路径
// registry.addInterceptor(loginUserInterceptor).addPathPatterns("/*");
}
@Override
public void configurePathMatch(PathMatchConfigurer pathMatchConfigurer) {
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer contentNegotiationConfigurer) {
}
@Override
public void configureAsyncSupport(AsyncSupportConfigurer asyncSupportConfigurer) {
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer defaultServletHandlerConfigurer) {
}
@Override
public void addFormatters(FormatterRegistry formatterRegistry) {
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) {
}
@Override
public void addCorsMappings(CorsRegistry corsRegistry) {
}
@Override
public void addViewControllers(ViewControllerRegistry viewControllerRegistry) {
}
@Override
public void configureViewResolvers(ViewResolverRegistry viewResolverRegistry) {
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> list) {
}
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> list) {
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> list) {
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> list) {
}
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> list) {
}
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> list) {
}
@Override
public Validator getValidator() {
return null;
}
@Override
public MessageCodesResolver getMessageCodesResolver() {
return null;
}
}
4.在controller上添加注解
@RequestMapping("/toRegister")
@LoginUser(role = "tester")
public String toRegister(Model model, HttpServletRequest request) {
return "register";
}

浙公网安备 33010602011771号