为了方便我们在日常开发注解的使用,本文将开发所需要的注解统一并进行归类起来,并结合用例进行解析,这样收藏起来以便日后使用。最主要本文将持续更新日常使用的注解,也可以评论中告知其他注解。
1依赖注入
1.1组件注解 @component
@component,而其余 @Controller、@Service、@Repository都组合了@component注解,主要为便于使用者Class组件进行归类。默认加载IOC容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作
注解 | 解析 | 用法 |
---|---|---|
@Component | 组件注解,使用了该注解会基于注释的配置和类路径扫描时,会自动扫描并加载Class到ICO容器中 | 注释在类上 |
@Controller | 应用在MVC层(控制层)DispatcherServlet会自动扫描注解了此注解的类,然后将web请求映射到注解了@RequestMapping的方法上 | 注释在类上 |
@Service | 应用在service层(业务逻辑层 | 注释在类上 |
@Repository | 应用在dao层(数据访问层) | 注释在类上 |
1.2依赖注入注解
@Autowired和@Inject、@Resource,可以与@Qualifier或者@Name配合使用,防止多实例注入时出错,以及值注入@Value。
注解 | 解析 | 用法 |
---|---|---|
@Autowired | 通过AutowiredAnnotationBeanPostProcessor类实现的依赖注入,默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,则需要限定其中一个候选者,否则将抛出异常。 | 可注释在字段上,在方法上 |
@Inject | 作用与@Autowired一样 | 可注释在字段上,在方法上、构造器上 |
@Resource | 默认按照名称进行装配,名称可以通过name属性进行指定 | 可注释在字段上,在方法上 |
@Qualifier | 限定描述符除了能根据名字进行注入,更能进行更细粒度的控制如何选择候选者,可与@Autowired或者@Inject进行组合使用,进行精确注入 | 可注释字段上,在方法上、参数上以及注解中 |
1.3 作用域和生命过程
@Scope,具有4个作用域可看Scope作用域以及涉及的问题章节,以及生命周期过程处理@PostConstruct、@PreDestroy 。
注解 | 解析 | 用法 | |
---|---|---|---|
@Scope | 具有4个作用域singleton,prototype,session,request,默认为singleton单例模式 | 可注释在Class创建时 | 可注释在Class上、接口、方法上 |
@PostConstruct | 相当于init-method,使用在方法上,当Bean初始化时执行 | 可注释在方法上 | |
@PreDestroy | 相当于destory-method,使用在方法上,当Bean销毁时执行 | 可注释在方法上 |
1.4 章节用例(结合1.1、1.2、1.3小节)
@Service //组件注入,注明为service组件
@Scope("prototype")//声明Scope为Prototype
public class UseFunctionService {
@Autowired //默认按type注入
@Qualifier("functionService") //精确注入
FunctionService functionService;
@Resource(name="baseDao")//默认按name注入,可以通过name和type属性进行选择性注入
private BaseDao baseDao;
@Inject
@Qualifier("userServiceImpl") //精确注入
public IUserService userService;
@PostConstruct//执行完构造函数后执行
public postConstruct(){
System.out.println("postConstruct");
}
@PreDestroy//在销毁Bean前执行
public perDestroy(){
System.out.println("perDestroy");
}
@Autowired
public void setUserDao(@Qualifier("userDao") UserDao userDao) {
this.userDao = userDao;
}
public String SayHello(String word){
return functionService.sayHello(word);
}
}
2. 配置注解
2.1 @Configuration配置注解
@Configuration可替换xml配置文件进行配置。被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。可与@PropertySource一起使用。
@Configuration作为元注解延伸了@SpringBootConfiguration
注解 | 解析 | 用法 |
---|---|---|
@Configuration | 配置类注解,可以与@Beae、@PropertySource一起使用,进行配置 | 注释在类、接口、枚举上 |
@SpringBootConfiguration | 组合注解,@Configuration配置、@EnableAutoConfiguration启用自动配置、@ComponentScan默认扫描@SpringBootApplication所在类的同级目录以及它的子目录 | 可注解在类上 |
@AutoConfigureAfter | 在指定的自动配置类之后再配置 | 可注解在类上 |
2.2扫描注解
@ComponentScan注解,被@Configuration注解标注的类上面,涉及了@filter过滤器注解
注解 | 解析 | 用法 |
---|---|---|
@ComponentScan | 定义扫描的路径,默认就会加载标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中,excludeFilters 指定扫描的时候需要排除的组件,includeFilters 指定扫描的时候只包含的组件 | 可注解在类Class |
@ComponentScans | 包含着@ComponentScan数组 | 可注解在类Class |
@filter | 声明要用作包含过滤器或排除过滤器的类型过滤器 | 可注解在@ComponentScan中 |
2.3 资源、值等注入注解
可以将配置文件、配置文件中的属性、以及系统属性等注入所需的字段中,或者bean中
注解 | 解析 | 用法 |
---|---|---|
@Value | 值注入,可以注入普通字符,系统属性,表达式运算结果,其他Bean的属性,文件内容,网址请求内容,配置文件属性值等等 | 可注释在字段上,方法上、参数上 |
@Bean | 声明当前方法的返回值为一个Bean,而且返回的Bean对应的类中可以定义init()方法和destroy()方法,然后在@Bean(initMethod=”init”,destroyMethod=”destroy”)定义,在构造之后执行init,在销毁之前执行destroy | 注解在方法上,注解上 |
@PropertySource | 指定配置文件位置,与@configuration类一起使用 | 注解在类Class、接口上 |
@ImportResource | 加载xml配置文件 | 注解在类Class、接口上 |
@ConfigurationProperties | 将properties属性与一个Bean及其属性相关联 | 可注解在类上、接口上 |
@Import | 用来导入配置类的 | 可注解在类上、接口上 |
2.4 条件注解 @Conditional
@Conditional根据满足某一特定条件创建特定的Bean,基于@Conditional元注解可延伸很多条件注解。
注解 | 解析 | 用法 |
---|---|---|
@ConditionalOnBean | Spring容器中是否存在对应的实例,可以通过实例的类型、类名、注解、昵称去容器中查找(可以配置从当前容器中查找或者父容器中查找或者两者一起查找)这些属性都是数组,通过”与”的关系进行查找 | 可注解方法上 |
@ConditionalOnClass | 类加载器中是否存在对应的类,逻辑跟@ConditionalOnBean类似 | 可注解在方法上、类Class、接口上 |
@ConditionalOnExpression | 判断SpEL 表达式是否成立 | 可注解在方法上、类Class、接口上 |
@ConditionalOnJava | 指定Java版本是否符合要求 | 可注解在方法上、类Class、接口上 |
@ConditionalOnMissingBean | Spring容器中是否缺少对应的实例,逻辑跟@ConditionalOnBean类似 | 可注解在方法上、类Class、接口上 |
@ConditionalOnMissingClass | Spring容器中是否缺少对应的实例,逻辑跟@ConditionalOnBean类似 | 可注解在方法上、类Class、接口上 |
@ConditionalOnNotWebApplication | 应用程序是否是非Web程序,没有提供属性,只是一个标识 | 可注解在方法上、类Class、接口上 |
@ConditionalOnProperty | 应用环境中的屬性是否存在,逻辑跟@ConditionalOnBean类似 | 可注解在方法上、类Class、接口上上 |
@ConditionalOnResource | 是否存在指定的资源文件。只有一个属性resources,是个String数组。会从类加载器中去查询对应的资源文件是否存在可注解在方法上、类Class、接口上 | |
@Profile | 指定某个bean属于哪一个profile:spring.profiles.active和spring.profiles.default(默认) | 可注解在方法上,类class、接口上 |
2.5 章节用例(2.1、2.2、2.3、2.4小节)
@Configuration
//@SpringBootConfiguration
@ComponentScan(value="com.cn",ComponentDefaultFilters=true,
includeFilters={
@Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
@Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})
})
@ImportResource("classpath:condition.xml")//导入xml配置
@Import(ConditionConfig.class)//导入ConditionConfig Class,并会实例化到容器中以及ConditionConfig中的配置也一起注入
public class Config {
@Value("I Love You!") //注入普通字符
private String normal;
@Value("#{systemProperties['os.name']}") //注入操作系统属性
private String osName;
@Value("#{ T(java.lang.Math).random() * 100.0 }") //注入表达式运算结果
private double randomNumber;
@Value("#{demoService.another}") //注入其他Bean的属性
private String fromAnother;
@Value("classpath:org/light4j/sping4/usually/el/test.txt") //注入文件内容
private Resource testFile;
@Value("http://www.baidu.com") //注入网址内容
private Resource testUrl;
@Value("${book.name}") //注入属性文件
private String bookName;
@Bean//加载bean
@Conditional(WindowsCondition.class) // 通过@Conditional注解,符合Windows条件则true
@ConditionalOnResource(resources="classpath:windows.ini")//在类路径下是否存在windows.ini文件,存在为true,最后进行注解与操作,为true实例化Bean
public ListService windowsListService(){
return new WindowsListService();
}
@Bean
@ConditionalOnClass(LinuxCondition.class) // 通过@ConditionalOnClass注解,符合Linux条件则true
@ConditionalOnProperty(name = "synchronize", havingValue = "true"))//如果synchronize在配置文件中并且值为true
public ListService linuxListService(){
return new LinuxListService();
}
//加载配置文件中前缀为spring.datasource的属性
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource jwcDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConditionalOnMissingClass({LinuxCondition.class,WindowsCondition.class})//当容器中缺失这两个Class时为true
@Profile("dev")//在dev环境下为true 最后结果为注解和之与,true实例化该Bean
public ListService macListService(){
return new MacListService();
}
}
3. 验证注解
验证注解在javax.validation包下:
注解 | 解析 | 用法 |
---|---|---|
@Valid | 启动校验,Errors参数要紧跟在带有@Valid注解的参数后面,@Valid注解所标注的就是要检验的参数 | 可注释在字段、方法、构造器、参数上 |
@AssertFalse | 所注解的元素必须是Boolean类型,并且值为false | 可注释在字段、方法、构造器、参数上 |
@AssertTrue | 所注解的元素必须是Boolean类型,并且值为true | 可注释在字段、方法、构造器、参数上 |
@DecimalMax | 所注解的元素必须是数字,并且它的值要小于或等于给定的BigDecimalString值 | 可注释在字段、方法、构造器、参数上 |
@DecimalMin | 所注解的元素必须是数字,并且它的值要大于或等于给定的BigDecimalString值 | 可注释在字段、方法、构造器、参数上 |
@Digits | 所注解的元素必须是数字,并且它的值必须有指定的位数 | 可注释在字段、方法、构造器、参数上 |
@Future | 所注解的元素的值必须是一个将来的日期 | 可注释在字段、方法、构造器、参数上 |
@Max | 所注解的元素必须是数字,并且它的值要小于或等于给定的值 | 可注释在字段、方法、构造器、参数上 |
@Min | 所注解的元素必须是数字,并且它的值要大于或等于给定的值 | 可注释在字段、方法、构造器、参数上 |
@NotNull | 所注解元素的值必须不能为null | 可注释在字段、方法、构造器、参数上 |
@Null | 所注解元素的值必须为null | 可注释在字段、方法、构造器、参数上 |
@Past | 所注解的元素的值必须是一个已过去的日期 | 可注释在字段、方法、构造器、参数上 |
@Pattern | 所注解的元素的值必须匹配给定的正则表达式 | 可注释在字段、方法、构造器、参数上 |
@Size | 所注解的元素的值必须是String、集合或数组,并且它的长度要符合给定的范围 | 可注释在字段、方法、构造器、参数上 |
4.AOP
4.1 AspectJ的注解式切面编程:
AspectJ的注解式在org.aspectj包下
注解 | 解析 | 用法 |
---|---|---|
@Aspect | 声明该类是一个切面 | 可注解在类Class、接口上 |
@After | 通知方法会在目标方法返回或抛出异常后调用 | 可注解在方法上 |
@Before | 通知方法会在目标方法调用之前执行 | 可注解在方法上 |
@Around | 通知方法会将目标方法封装起来 | 可注解在方法上 |
@AfterReturning | 通知方法会在目标方法返回后调用 | 可注解在方法上 |
@AfterThrowing | 通知方法会在目标方法抛出异常后调用 | 可注解在方法上 |
@Pointcut | 能够在一个@AspectJ切面内定义可重用的切点,(通过@Pointcut注解声明频繁使用的切点表达式) | 可注解在方法上 |
@annotation | 限定匹配带有指定注解的连接点 | 可注解在建言(advice)上,如@After等 |
@EnableAspectJAutoProxy | 开启Spring对AspectJ的支持,在配置类上 | 可注解在类Class、接口上 |
4.2 AspectJ指示器
execution指示器是我们在编写切点定义时最主要使用的指示器:
注解 | 解析 | 用法 |
---|---|---|
AspectJ指示器 | 描 述 | |
arg() | 限制连接点匹配参数为指定类型的执行方法 | 可注释在AspectJ的注解式、如@After等 |
@args() | 限制连接点匹配参数由指定注解标注的执行方法可注释在AspectJ的注解式,如@After等 | |
execution() | 用于匹配是连接点的执行方法 | 可注释在AspectJ的注解式,如@After等 |
this() | 限制连接点匹配AOP代理的bean引用为指定类型的类 | 可注释在AspectJ的注解式,如@After等 |
Target | 限制连接点匹配目标对象为指定类型的类可注释在AspectJ的注解式,如@After等 | |
@target() | 限制连接点匹配特定的执行对象,这些对象对应的类要具有指定类型的注解 | 可注释在AspectJ的注解式,如@After等 |
within() | 限制连接点匹配指定的类型 | 可注释在AspectJ的注解式,如@After等 |
@within() | 限制连接点匹配指定注解所标注的类型(当使用Spring AOP时,方法定义在由指定的注解所标注的类里) | 可注释在AspectJ的注解式,如@After等 |
4.3 用例:编写切面
@Aspect //声明该类是一个切面
@Component
public class LogAspect {
private final String POINT_CUT ="execution(* org.sping4.ccww.aop.DemoMethodService.*(..))";
@Pointcut("@annotation(org.ccww.sping4.base.aop.Action)") //声明切面
public void annotationPointCut(){};
@After("annotationPointCut()") //声明一个建言,并使用@Pointcut定义的切点
public void after(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Action action = method.getAnnotation(Action.class);
System.out.println("注解式拦截 " + action.name()); //⑤
}
@Before("execution(* org.sping4.ccww.aop.DemoMethodService.*(..))")//声明一个建言,此建言直接使用拦截规则作为参数
public void before(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("方法规则式拦截,"+method.getName());
}
/**
* 后置返回
* 如果第一个参数为JoinPoint,则第二个参数为返回值的信息
* 如果第一个参数不为JoinPoint,则第一个参数为returning中对应的参数
* returning:限定了只有目标方法返回值与通知方法参数类型匹配时才能执行后置返回通知,否则不执行,
* 参数为Object类型将匹配任何目标返回值
*/
@AfterReturning(value = POINT_CUT,returning = "result")
public void doAfterReturningAdvice1(JoinPoint joinPoint,Object result){
System.out.println("第一个后置返回通知的返回值:"+result);
}
}
5. Spring MVC
注解 | 解析 | 用法 | |
---|---|---|---|
@EnableWebMvc | 会开启一些默认配置,如一些ViewResolver或者MessageConverter等 | 可注解在类Class、接口上 | |
@RequestMapping | 用来映射Web请求(访问路径和参数),处理类和方法的(即配置URL和方法之间的映射),注解在方法上的@RequestMapping路径会继承注解在类上的路径 | 可注解在类Class、接口上、方法上 | |
@ResponseBody | 支持将返回值放在response体内 | 可注解在返回值前或者方法上 | |
@RequestBody | 允许requ | est的参数在request体内 | 可注解在参数前 |
@PathVariable | 用来接收路径参数,如/ccww/003,可接收003作为参数 | 可注解在参数前 | |
@RestController | 组合注解,组合了@Controller和@ResponseBody,这就意味着当你只开发一个和页面交互数据的控制的时候,需要使用此注解。若没有此注解,要想实现上述功能,则需要自己在代码中加@Controller和@ResponseBody两个注解 | 可注解在类Class、接口上 | |
@ModelAttribute | 绑定请求参数到命令对象、暴露@RequestMapping 方法返回值为模型数据、暴露表单引用对象为模型数据 | 可注解在方法、参数上 |
用例:
@Controller //声明此类是一个控制器
@RequestMapping("/ccww") //映射此类的访问路径是/ccww
//@RestController // 使用@RestController,声明是控制器,并且返回数据时不需要@ResponseBody
//@RequestMapping("/ccww")
public class DemoAnnoController {
//此方法未标注路径,因此使用类级别的路径/anno;produces可定制返回的response的媒体类型和字符集,或返回值是json对象,则设置porduces="application/json;charset=UTF-8"
@RequestMapping(produces = "text/plain;charset=UTF-8")
public @ResponseBody String index(HttpServletRequest request) { //可接受HttpServletRequest作为参数,当然也可以接受HttpServletResponse作为参数。此处的@ResponseBody用在返回值前
return "url:" + request.getRequestURL() + " can access";
}
@RequestMapping(value = "/demoPathVar/{str}", produces = "text/plain;charset=UTF-8")//
public @ResponseBody String demoPathVar(@PathVariable String str, //接受路径参数,并在方法参数前结合@PathVariable使用,访问路径为/ccww/demoPathVar/xxx
HttpServletRequest request) {
return "url:" + request.getRequestURL() + " can access,str: " + str;
}
//常规的request参数获取,访问路径为/ccww/requestParam?id=1
@RequestMapping(value = "/requestParam", produces = "text/plain;charset=UTF-8")
public @ResponseBody String passRequestParam(Long id,
HttpServletRequest request) {
return "url:" + request.getRequestURL() + " can access,id: " + id;
}
@RequestMapping(value = "/obj", produces = "application/json;charset=UTF-8")
@ResponseBody // 可注解在方法上
public String passObj(DemoObj obj, HttpServletRequest request) {
return "url:" + request.getRequestURL()
+ " can access, obj id: " + obj.getId()+" obj name:" + obj.getName();
}
//映射不同的路径到相同的方法,访问路径为/anno/name1或/anno/name2
@RequestMapping(value = { "/name1", "/name2" }, produces = "text/plain;charset=UTF-8")
public @ResponseBody String remove(HttpServletRequest request) {
return "url:" + request.getRequestURL() + " can access";
}
@RequestMapping(value = "/helloWorld")
//以“user”为名称添加到模型对象中供视图页面展示使用
public String helloWorld(@ModelAttribute User user) {
return "helloWorld";
}
}
6.后续将更新更多注解,如(test测试、@EnableXXX,spring boot以及spring cloud注解等)
欢迎转载,标明出处!!!