注解相信大家对它并不是很陌生,在我们平时的开发中几乎天天都在使用注解尤其是在springBoot出现后几乎之前所有使用xml的配置都可以使用注解来替代。今天我来介绍一下java中的注解。
1.注解应用场景
在原生java中就内置了几个注解有@Override、@Deprecated、@SuppressWarnings等。这几个注解相信我们并不陌生,其中@Override用来修饰一个方法,表示方法不是当前类先声明的,当前类只是重写了这个方法。如果当前类的任何父类或者接口都没有声明过该方法那么java在编译的时候就会报错。当然如果当前类确实是重写了父类的方法就算忘记加@Override这个注解java编译器也不会报错。@Deprecated表示过时的类或方法。@SuppressWarnings表示压制java的编译警告,它有一个必传的参数表示压制哪种类型的警告。java提供的内置注解比较的简单,这里我就不写代码实验了。
注解的另一个使用场景是在一些IOC的框架中使用。现在的java开发经常使用框架来管理对象的生命周期,使用这些框架时,程序员一般不会自己去new对象而是由框架来负责创建对象并且由框架来负责管理对象之间的依赖关系,这就是我们常说的控制反转和依赖注入。spring框架就是一个典型的ioc框架,我会在以后文章中专门介绍这个框架。在使用spring开发中我们使用@Controller来注册一个bean,然后使用@Autowired这个注解来注入到其他类的属性字段。例如:
@Controller public class UserController { @Autowired private UserService userService; @Autowired private OrderService orderService; }
这样做的好处是可以让代码变得更加的简单,而且容器可以根据配置返回一个代理对象,实现动态代理。
Servlet3.0已经开始支持使用注解来定义Servlet,当然我们还是需要继承HttpServlet然后只需要在类上加上@WebServlet这个注解即可,例如
@WebServlet(urlPatterns = "/test", asyncSupported = true) public class TestServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override public void init(ServletConfig config) throws ServletException { super.init(config); System.out.println(config.getServletContext()); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println(this.getServletConfig().getServletContext()); } }
2.创建注解
定义注解使用@interface,另外它还有两个元注解@Target和@Retention,这两个注解是专门用来定义注解的。@Target表示的是注解的目标,@Retention表示注解信息保留到什么时候。在@Target中可以传一个值,这个值在java中使用的是一个枚举类型ElementType,其中ElementType.TYPE表示类、接口(包括注解)、枚举的声明,ElementType.FIELD表示字段的声明,ElementType.METHOD表示方法声明,ElementType.PARAMETER表示参数的声明,没有声明时表示适用所有。在@Retention也可以传入一个值,它是使用RetentionPolicy这个枚举来定义,这个枚举有三个值分别是SOURCE表示只在源码中保留在编译为Class文件后就会丢掉,CLASS表示保留到字节码文件中但是java虚拟机把class文件加载进入内存时不一定在内存中保留,RUNTIME会一直保留到运行时,没有声明时默认是ClASS。无论是@Target还是@Retention里面都可以传入多个值,使用{}表示。下面我们来定义一个注解:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.CLASS) public @interface Action { boolean isSingle() default true; String [] value(); String [] url(); }
我们可以在注解中定义方法,然后在使用注解时就需要在注解中按照方法的返回类型使用方法名赋值例如我要使用我定义的这个注解:
@Action(url={"/user","/userhonme"},value={"userController"}) public class UserController { }
isSingle没有赋值是因为这个方法有默认值。注意当只有一个参数且参数名为value时提供参数值时可以省略"value="。如果注解中定义的方法的返回值为String那么默认值不可以为null但可以是" "。