对于java的注解,在工作和学习过程经常有碰到,也一直在使用。但是很多时候是知其然,不知其所以然!
Java注解是什么?
一种代码级别的说明,它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
Java 5.0引入新特性
作用分类:
- 编写文档:通过代码里标识的元数据生成文档(生成文档doc文档)
- 代码分析:通过代码里标识的元数据对代码进行分析(使用反射)
- 编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查(@Override)
1、基本概念
元注解:就是负责注解其他注解,Java5.0定义了4个标准的meta-annotation类型
- @Target
作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
取值(ElementType)有:
1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明 - @Retention
作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
取值(RetentionPoicy)有:
1.SOURCE:在源文件中有效(即源文件保留,而被编译器丢弃)
2.CLASS:在class文件中有效(即class保留,被虚拟机忽略)
3.RUNTIME:在运行时有效(即运行时保留) - @Documented
作用:用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。@Documented是一个标记注解,没有成员 - @Inherited
作用:阐述了某个被标注的类型是可以被子类继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。@Inherited也是一个标记注解。
2、注解定义
定义注解格式:
public @interface 注解名 {定义体}
注解参数的可支持数据类型:
- 所有基本数据类型(int,float,boolean,byte,double,char,long,short)
- String类型
- Class类型
- enum类型
- Annotation类型
以上所有类型的数组
注:注解元素必须有确定的值,要么在定义注解的默认值中指定,要么在使用注解时指定,非基本类型的注解元素的值不可为null。
3、示例
一个获取注解的示例:
Class cl = TestClass.class;
//获取类注解
cl.getAnnotations();
Method[] methods = cl.getDeclaredMethods();
for (Method method : methods) {
//获取方法注解
Annotation[] methodAnnotations = method.getDeclaredAnnotations();
//获取参数注解
Annotation[][] methodParamAnnotations = method.getParameterAnnotations();
}
注:此种方式只能获取到@Retention为RUNTIME运行时有效的注解。
Java自带注解
@Override
作用:表示子类要重写父类的对应方法。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。
注:@override注解在JDK 5环境下只能用于对继承的类的方法的重写,实现接口中的方法不能用@override注解,但是JDK1.6可以。
@Deprecated
作用:表示方法已过期,不被建议再使用。
@SuppressWarnings
作用:表示抑制警告
Spring注解
1、spring 常见
@Autowired
@Autowired、@Resource和@Inject三者对比
@Autowired
1、Spring提供的注解(org.springframework.beans.factory.annotation.Autowired)
2、有个属性为required,可以配置为false,如果配置为false之后,当没有找到相应bean的时候,系统不会抛错。
3、默认按类型注入,‘AutowiredAnnotationBeanPostProcessor’ 类实现的依赖注入
4、支持 @Qualifiers限定和@Name匹配@Resource
1、jsr250规范的实现(javax.annotation)
2、默认通过名字注入,CommonAnnotationBeanPostProcessor’ 类实现依赖注入
3、名字匹配注入失败后尝试用类型进行注入
4、支持 @Qualifiers限定,不支持@Name匹配- @Inject
1、jsr330中的规范(javax.inject)
2、默认按类型注入,‘AutowiredAnnotationBeanPostProcessor’ 类实现的依赖注入
3、支持 @Qualifiers限定和@Name匹配
参考:http://blog.csdn.net/u012734441/article/details/51706504
@Component(不推荐使用)
是所有受Spring 管理组件的通用形式,@Component注解可以放在类的头上
@ Service
对应的是业务层Bean
@ Repository
对应数据访问层Bean
@Bean
@Scope
可以通过bean 的scope 属性来定义一个Bean 的作用范围(生命周期)
@Scope中可以指定如下值:
- singleton:定义bean的范围为每个spring容器一个实例(默认值)
- prototype:定义bean可以被多次实例化(使用一次就创建一次)
- request:定义bean的范围是http请求(springMVC中有效)
- session:定义bean的范围是http会话(springMVC中有效)
- global-session:定义bean的范围是全局http会话(portlet中有效)
@Required
@ required 负责检查一个bean在初始化时其声明的 set方法是否被执行, 当某个被标注了 @Required 的 Setter 方法没有被调用,则 Spring 在解析的时候会抛出异常,以提醒开发者对相应属性进行设置。 @Required 注解只能标注在 Setter 方法之上。
@Qualifier
使用@Autowired 时,如果找到多个同一类型的bean,则会抛异常,此时可以使用
@PostConstruct
在方法上加上注解@PostConstruct ,这个方法就会在Bean 初始化之后被Spring 容器执 行
@PreDestroy
在方法上加上注解@PreDestroy ,这个方法就会在Bean 被销毁前被Spring 容器执行。
AOP相关注解:
@Aspect 定义一个切面
@Pointcut 定义一个切点,如@Pointcut(“execution(* com.mogujie.service.cube.controller.auth..(..))”),表达式定义可参考:http://blog.csdn.net/mike8785/article/details/5444265
定义通知:
@Around
@Before
@After
@AfterThrowing
@AfterReturning
…
2、spring mvc
@Controller
表现层的Bean,也就是Action
@RequestMapping
@RequestParam
@PathVariable
@ResponseBody
3、spring boot
@SpringBootApplication(组合注解)
@Configuration
@EnableAutoConfiguration
@ComponentScan
4、其他常用spring注解
@Transational 用于事务控制的
@Import
@ImportResource
其他常用开源框架注解
Junit
这里的Junit是指Junit 4,老版本的可能存在一些差异。
@Test
测试方法,在这里可以测试期望异常和超时时间
注意:测试方法必须是public void,即公共、无返回数据。可以抛出异常
@Test注解提供2个参数:
1,“expected”,定义测试方法应该抛出的异常,如果测试方法没有抛出异常或者抛出了一个不同的异常,测试失败
2,“timeout”,如果测试运行时间长于该定义时间,测试失败(单位为毫秒)
public class MathTest {
@Test(expected=Exception.class)
public void testAdd() throws Exception{
throw new Exception();
}
@Test(timeout=5000)
public void testAdd() {
for(;;){
}
}
}
@Before
初始化方法,每个测试方法之前都会执行一次
@BeforeClass
测试方法前执行,针对所有测试,只执行一次,且必须为static void
@After
释放资源,每个测试方法之前都会执行一次
@AfterClass
测试方法后执行,针对所有测试,只执行一次,且必须为static void
@Ignore
忽略的测试方法
@RunWith
测试运行器,放在测试类名之前,用来确定测试类怎么运行的,当不指定这个注解时,使用默认Runner来运行测试代码,即@RunWith(JUnit4.class)。常见的运行器有:
(1)@RunWith(Parameterized.class):参数化运行器,配合@Parameters使用JUnit的参数化功能。
(2)@RunWith(Suite.class)
@SuiteClasses({ATest.class,BTest.class,CTest.class})
测试集运行器配合使用测试集功能。
(3)@RunWith(JUnit4.class):JUnit 4的默认运行器
(4)@RunWith(JUnit38ClassRunner.class):用于兼容junit3.8的运行器
这个是指定使用的单元测试执行类,如spring测试就指定的是SpringJUnit4ClassRunner.class;
(5)@ContextConfiguration()指定上下文配置文件
示例:
private static ApplicationContext context;
@BeforeClass
public static void setUp() throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("/beans.xml");
Object test = context.getBean("OBJECT");//通过spring上下文获取bean
}
@Test
public void test(){
//TEST SOMETHING
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebIntegrationTest("server.port:0")
public class BigSaleControllerTest {
@Autowired
protected WebApplicationContext context;//直接注入bean
@Value("${local.server.port}")
protected int port;
@Test
public void test(){
//TEST SOMETHING
}
@Parameters
用于JUnit的参数化功能,用来标记准备数据的方法。
参考文档
http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html