一、元注解:Meta-Annotation,是Java预定义的注解,被Java编译器使用,会对普通注解的行为产生影响。
包括:Retention,Target
二、普通注解,自定义注解
/**
*@ClassName:AnnocationTest.java
*@Description:TODO
*@Version:V1.0.1
*@Date:May 23, 2016
*@UpdateInfo Version ModiSerial ModiReason Modify-Author
*/
package com.cola.invocation;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
/**
* @author wanghong11609
*
*/
public class AnnocationTest {
public static void main(String[] i){
Foo foo=new Foo();
Method[] methods=Foo.class.getDeclaredMethods();
for(Method m:methods){
if(m!=null&&m.getAnnotation(NeedTest.class).value()){
try {
m.invoke(foo, null);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
//枚举类型,定义注解存在期的可选值
enum RetentionPolicy {
SOURCE,//处理注解的方式:将被编译器废弃
CLASS,//处理注解的方式:编译器会保留到class文件中,但是虚拟机运行时不保留;这是注解的默认的处理
RUNTIME//处理注解的方式:编译器会保留到class文件中,虚拟机运行时保留,因此可以通过反射的方式获取并使用
}
//注解,指定注解存在时期
public @interface Retention {
RetentionPolicy value();//如果注解只有一个成员,必须命名为value()
}
//注解,指定使用注解的目标类型
public @interface Target {
//成员类型是受限的,合法的类型包括原始类型及其封装类、String、Class、enums、注解类型,以及上述类型的数组类型
ElementType[] value();
}
//枚举类型,定义使用注解的目标类型的值
enum ElementType {
TYPE,//类,接口(包括注解类型),或者枚举声明
FIELD,//字段声明,包括枚举
METHOD,//方法声明
PARAMETER,//正常参数定义
CONSTRUCTOR,//构造器声明
LOCAL_VARIABLE,//Local variable declaration
ANNOTATION_TYPE,//注解类型声明
PACKAGE,//包声明
TYPE_PARAMETER,//Type parameter declaration
TYPE_USE//Use of a type
}
//Package、Class、Constructor、Method、Field新增的访问注解的方法,通过泛型直接返回注解对象
<T extends Annotation>T getAnnotation(Class<T> annotationClass){
return null;
}
}
//自己定义注解
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(java.lang.annotation.ElementType.METHOD)
@interface NeedTest{
boolean value() default true;
}
class Foo{
@NeedTest(true)
public void one(){
System.out.println("one");
}
@NeedTest(false)
public void two(){
System.out.println("two");
}
}
三、Spring注解说明
Spring的bean容器中处理的bean大概可以分为两种,(1)以属性为主要信息的bean对象,(2)以服务方法为主要内容的服务类
@Autowired
@Autowired默认按类型(如果变量类型是接口或者父类,则会查找接口的所有实现或者父类的所有子类)匹配的方式在容器查找匹配的bean,当且仅当只有一个匹配的bean时,Spring将其注入到@Aotuwired标注的变量中
@Autowired注解标注的变量,Spring在注入时会自动处理set和get方法
@Autowired(required=false) required属性定义在异常时的处理方法,如果Spring匹配不到对应的bean,required =true时将抛出异常,required=false将默认变量为null
public class CarFactory {
//这里Spring会查找配置的ICar的实现和子类Bean
@Autowired
private ICar car;
public String toString(){
return car.getCarName();
}
}
private ICar car;
public String toString(){
return car.getCarName();
}
}
@Qualifier
该注解根据bean的id名称来匹配并注入。
public class CarFactory {
//此处会注入名为"bmwCar"的Bean。
@Autowired
@Qualifier("bmwCar")
private ICar car;
public String toString(){
return car.getCarName();
}
}
@Qualifier("bmwCar")
private ICar car;
public String toString(){
return car.getCarName();
}
}
@Resource
该注解的注入顺序如下:
- 不指定参数,默认通过name(id)属性去匹配bean,找不到再按type去匹配;
- 指定了name或者type则根据指定的类型去匹配bean;
- 指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错
@Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配;
@Autowired是Spring的注解,@Resource是J2EE的注解,查看导入注解的包名就知道了;
因此,建议使用@Resource注解,以减少代码和Spring之间的耦合。
public class Zoo {
@Resource(name="tiger")
private Tiger tiger;
@Resource(type=Monkey.class)
private Monkey monkey;
public String toString(){
return tiger + "\n" + monkey;
}
}
@Service注解
@Service注解的含义
- 声明被声明的类是一个Bean
- 被声明的类的name(bean id)默认是类名首字母小写的字符串;被声明id可以作为参数指定
引用案例
beans.xml只要配置这一句:
<context:component-scan base-package="com.spring" />
@Service
public class Monkey {
private String monkeyName = "MonkeyKing";
public String toString(){
return "MonkeyName:" + monkeyName;
}
}
@Service
public class Tiger {
private String tigerName="TigerKing";
public String toString(){
return "TigerName:"+tigerName;
}
}
@Service("Zoo")
@Scope("prototype")
public class Zoo {
@Autowired
private Tiger tiger;
@Autowired
private Monkey monkey;
public String toString(){
return tiger + "\n" + monkey;
}
}
注解注入的Bean只能用Spring容器获取对象时会生效,参考:
public static void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] {"Beans.xml" });
Mid one=(Mid)context.getBean("mid");
one.test();
//((new Mid()).test())报错,zoo没有初始化
}
@Scope注解
和xml配置参数的意义一样,@Scope指定类的创建模式,singleton和prototype
四、JSR330注解说明
@Inject
@Named
@Qualifier
五、注解的作用
- 1.用于辅助理解
- 2.用于代码控制
- 3.用于框架便利(Spring)
六、Spring的bean配置文件
Spring的bean有多种类型,一般分开在多个文件中;命名类似application-mvc.xml的一般放Spring的插件配置,命名类似beans.xml的一般配置对象bean。
- 利用注解向Spring容器注册bean
<context:component-scan base-package="package1[,package2]" />
<!-- 多个包使用都好分开-->
以上参数指定包中,如果类的头上有@Component、@Repository、@Service、@Controller注解,Spring会把这个类注册到Spring的bean容器。
@Component是所有受Spring 管理组件的通用形式,@Component注解可以放在类的头上,@Component不推荐使用。
@Controller对应表现层的Bean,也就是Action,定义形式@Controller("name") or @Controller(value="name")
@Service对应业务层的bean
@Repository对应数据访问层bean,定义格式@Repository(value="daoName")
七、Spring常用注解
@Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean。
@Scope注解 作用域
@Lazy(true) 表示延迟初始化
@Service用于标注业务层组件、
@Controller用于标注控制层组件(如struts中的action)
@Repository用于标注数据访问组件,即DAO组件。
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@PostConstruct用于指定初始化方法(用在方法上)
@PreDestory用于指定销毁方法(用在方法上)
@DependsOn:定义Bean初始化及销毁时的顺序
@Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
@Autowired 默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:
@Qualifier("personDaoBean")
@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
@Async异步方法调用
@RequestMapping注解可以在控制器类级别和方法级别使用,说明Http请求将会交给那个控制器处理,或者调用控制器的那个方法。
路径映射的格式:
@RequestMapping(name) or @RequestMapping(value="name") or @RequestMapping(value={""[,""]}),@RequestMapping注解可以同时处理多个http的url请求
方法名映射的格式:
@RequestMapping(params = "method=getHostAccount")
HTTP请求类型指定的格式:
Spring处理HTTP请求都是默认处理成GET的
@RequestMapping(method=RequestMethod.GET)
RequestMethod的取值:GET,POST等
统一定义:@RequestMapping(name[key=value[,key=value]])
@RequestMapping的URL值可以使用正则表达式,例如:
@RequestMapping(value = "/fetch/{id:[a-z]+}/{name}", method = RequestMethod.GET)
consumes关键值指定消费对象:
@RequestMapping(value = "/cons", consumes = {"application/JSON", "application/XML"})
produces关键值指定产生对象:
@RequestMapping(value = "/prod", produces = {"application/JSON"})
@RequestParam注解指定处理方法的参数,可以配合@RequestMapping使用
格式:
@RequestParam不指定参数时,上传参数名和方法定义的参数名要一致,
@RequestParam(name|value="name"[,required=bool[,defaultValue=$]])
required参数是布尔值,定义参数是否是必输
defaultValue参数定义方法的参数的默认值
@ResponseBody 注解标注的方法Spring会把该方法的返回值转换成JSON对象,前台可以按Json格式使用返回值。所以返回值最好包装成合格的JSON格式。