Spring常用注解大全,值得你的收藏!!!

简介: 注解和 xml 都是一种元数据,元数据即解释数据的数据,就是所谓配置。在传统的Spring开发中是使用.xml文件来对bean进行注入或者是配置aop、事物,但是这么做有两个缺点:

废话部分


注解和 xml 都是一种元数据,元数据即解释数据的数据,就是所谓配置。在传统的Spring开发中是使用.xml文件来对bean进行注入或者是配置aop、事物,但是这么做有两个缺点:


1、如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大;如果按需求分开.xml文件,那么.xml文件又会非常多。所以这种做法导致配置文件的可读性与可维护性变得很低。


2、在开发中在.java文件和.xml文件之间不断切换,是一件麻烦的事,同时这种思维上的不连贯也会降低开发的效率。 问题都是用来解决的,所以为了解决.xml配配置文件带来的问题,Spring引入了注解,通过"@XXX"的方式,让注解与Java Bean紧密结合,注解方式减少了配置文件内容,更加便于管理,并且使用注解可以大大提高了开发效率!


本文按照分类讲解Spring中常用的一些注解。


正文部分


1、声明bean的注解


1、@Component:泛指各种组件,就是说当我们的类不属于各种归类的时候(不属于@Controller、@Services等的时候),我们就可以使用@Component来标注这个类,把普通pojo实例化到spring容器中,相当于配置文件中的:。所以可以理解为@Component可以细化为@Reposity,@Service,@Controller。


@Component("conversionImpl")
//其实默认的spring中的Bean id 为 conversionImpl(首字母小写)
public class ConversionImpl implements Conversion {
    @Autowired
    private RedisClient redisClient;
}
复制代码


2、@Service 在业务逻辑层使用(service层注入dao)用于标注服务层,主要用来进行业务的逻辑处理


@Service()
public class UserService{
    @Resource
    private UserDao userDao;
    public void add(){
        userDao.add();
    }
}
复制代码


3、@Repository:用于标注数据库访问层,也可以说被作为持久层操作(数据库)的bean来使用,即dao层。


@Repository(value="userDao")注解是告诉Spring,让Spring创建一个名字叫“userDao”的UserDaoImpl实例。当Service需要使用Spring创建的名字叫“userDao”的UserDaoImpl实例时,就可以使用@Resource(name = "userDao")注解告诉Spring,Spring把创建好的userDao注入给Service即可。


如果在DaoImpl中加了@Repository,那么在spring的扫包机制下,也会生成这个dao的bean,注入serviceImpl中的:


//也可以使用@Component,效果都是一样的,只是为了声明为bean
@Repository 
@Mapper
public interface UserDao {
  @Insert("insert into user(account, password, user_name) " +
            "values(#{user.account}, #{user.password}, #{user.name})")
    int insertUser(@Param("user") User user) throws RuntimeException;
}
复制代码


@Autowired
 private UserDao UserDao;
复制代码


4、@Controller 在展现层使用,控制器的声明。用于标记在一个类上,使用它标记的类就是一个SpringMvc Controller对象,分发处理器会扫描使用该注解的类的方法,并检测该方法是否使用了@RequestMapping注解。


@Controller只是定义了一个控制器类,而使用@RequestMapping注解的方法才是处理请求的处理器。


@Controller标记在一个类上还不能真正意义上说它就是SpringMvc的控制器,因为这个时候Spring还不认识它,这个时候需要把这个控制器交给Spring来管理。


@Controller
public class HelloWorld{
  @RequestMapping(value="/hello")
  public String hello() {
    return "hello";
  }
    @Autowried
    private IocSerevce service;
    public void add(){
        service.add();
    }
}
复制代码


2、注入bean的注解


1、@Autowired:在Spring 2.5 引入了 @Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法。在使用@Autowired之前,xml文件对一个bean配置起属性时,是这用的:


<property name="属性名" value=" 属性值"/>
复制代码


定义了一个UserRepository接口,其中定义了一个save方法:


public interface UserRepository {
    void save();
}
复制代码


再定义一个UserRepository接口的实现类,并实现save方法,在这里指定了该bean在IoC中标识符名称为userRepository。


@Repository("userRepository")
public class UserRepositoryImps implements UserRepository{
    @Override
    public void save() {
        System.out.println("UserRepositoryImps save");
    }
}
复制代码


需要一个UserRepository类型的属性,通过@Autowired自动装配方式,从IoC容器中去查找到,并返回给该属性:


@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    public void save(){
        userRepository.save();
    }
}
复制代码


2、@Inject:@Inject是JSR330 (Dependency Injection for Java)中的规范,需要导入javax.inject.Inject;实现注入。@Inject可以作用在变量、setter方法、构造函数上。是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Named。

将@Inject可以作用在变量、setter方法、构造函数上,和使用@Autowired一样:


public class User{
  private Person person;
  @Inject
  pbulic void setPerson(Person person){
    this.person = person;
  }
}
复制代码


3、@Named("XXX") 中的 XXX是 Bean 的名称,所以 @Inject和 @Named结合使用时,自动注入的策略就从 byType 转变成 byName 了。


public class User{
  private Person person;
  @Inject
  pbulic void setPerson(@Named("main")Person person)
{
    this.person = person;
  }
}
复制代码


4、@Resource:@Resource是JSR250规范的实现,需要导入javax.annotation实现注入。@Resource可以作用在变量、setter方法上。@Resource是根据名称进行自动装配的,一般会指定一个name属性。


public class User{
  private Person person;
  @Resource(name="myPerson")
  pbulic void setPerson(Person person){
    this.person = person;
  }
}
复制代码


@Autowired、@Inject和@Resource都可以注解在set方法和属性上,推荐注解在属性上。


3、配置类相关注解


1、@Bean:Spring的@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中。SpringIOC 容器管理一个或者多个bean,这些bean都需要在@Configuration注解下进行创建,在一个方法上使用@Bean注解就表明这个方法需要交给Spring进行管理。


@Configuration
public class AppConfig {
    // 未指定bean 的名称,默认采用的是 "方法名" + "首字母小写"的配置方式
    @Bean
    public MyBean myBean(){
        return new MyBean();
    }
}
public class MyBean {
    public MyBean(){
        System.out.println("MyBean Initializing");
    }
}
复制代码


@Bean 注解的属性有:value、name、autowire、initMethod、destroyMethod。


name 和 value 两个属性是相同的含义的, 在代码中定义了别名。为 bean 起一个名字,如果默认没有写该属性,那么就使用方法的名称为该 bean 的名称。  


autowire指定 bean 的装配方式, 根据名称 和 根据类型 装配, 一般不设置,采用默认即可。autowire指定的装配方式 有三种Autowire.NO (默认设置)、Autowire.BY_NAME、Autowire.BY_TYPE。


initMethod和destroyMethod指定bean的初始化方法和销毁方法, 直接指定方法名称即可,不用带括号。


public class MyBean {
    public MyBean(){
        System.out.println("MyBean Initializing");
    }
    public void init(){
        System.out.println("Bean 初始化方法被调用");
    }
    public void destroy(){
        System.out.println("Bean 销毁方法被调用");
    }
}
@Configuration
public class AppConfig {
//    @Bean
    @Bean(initMethod = "init", destroyMethod = "destroy")
    public MyBean myBean(){
        return new MyBean();
    }
}
复制代码


2、@Scope:@Scope 设置Spring容器如何新建Bean实例,默认是@scope("Singleton "),即单例模式。其设置类型包括:


Singleton (单例,一个Spring容器中只有一个bean实例,默认模式),
Protetype (每次调用新建一个bean),
Request (web项目中,给每个http request新建一个bean),
Session (web项目中,给每个http session新建一个bean),
GlobalSession(给每一个 global http session新建一个Bean实例)
复制代码


@Configuration
public class myConfig {
    //默认是单例的。不需要特别说明
    @Bean("person")
    public Person person(){
        return new Person("binghe002", 18);
    }
}
复制代码


@Configuration
public class myConfig {
    //Person对象的作用域修改成prototype,多例的
    @Scope("prototype")
    @Bean("person")
    public Person person(){
        return new Person("binghe002", 18);
    }
}
复制代码


3、@Configuration :从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。


//定义该类为配置类
@Configuration
public class myConfiguration {
    public myConfiguration() {
        System.out.println("myConfiguration容器启动初始化。。。");
    }
}
复制代码


4、@ComponentScan :@ComponentScan主要就是定义扫描的路径从中找出标识了需要装配的类自动装配到spring的bean容器中。前面说到过@Controller注解,@Service,@Repository注解,它们其实都是组件,属于@Component注解,而@ComponentScan注解默认就会装配标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中。


//扫描com.demo下的组件
@ComponentScan(value="com.demo")
@Configuration
public class myConfig {
}
复制代码


5、@WishlyConfiguration 为@Configuration与@ComponentScan的组合注解,可以替代这两个注解。


4、@Value注解


1、@Value :@Value的作用是通过注解将常量、配置文件中的值、其他bean的属性值注入到变量中,作为变量的初始值。 支持如下方式的注入:  (1)、普通注入


@Value("张三")
private String name; // 注入普通字符串
复制代码


(2)、bean属性、系统属性、表达式注入,使用@Value("#{}")。bean属性注入需要注入者和被注入者属于同一个IOC容器,或者父子IOC容器关系,在同一个作用域内。


// 注入其他Bean属性:注入beanInject对象的属性another,类具体定义见下面
@Value("#{beanInject.another}")
private String fromAnotherBean; 
// 注入操作系统属性
@Value("#{systemProperties['os.name']}")
private String systemPropertiesName; 
//注入表达式结果
@Value("#{T(java.lang.Math).random() * 100.0 }")
private double randomNumber;
复制代码


(3)、配置文件属性注入@Value("${}")


@Value("#{}")读取配置文件中的值,注入到变量中去。配置文件分为默认配置文件application.properties和自定义配置文件

•application.properties。application.properties在spring boot启动时默认加载此文件


•自定义属性文件。自定义属性文件通过@PropertySource加载。@PropertySource可以同时加载多个文件,也可以加载单个文件。如果相同第一个属性文件和第二属性文件存在相同key,则最后一个属性文件里的key启作用。加载文件的路径也可以配置变量,如下文的${anotherfile.configinject},此值定义在第一个属性文件config.properties


第一个属性文件config.properties内容如下:


${anotherfile.configinject}作为第二个属性文件加载路径的变量值


book.name=bookName


anotherfile.configinject=placeholder


第二个属性文件config_placeholder.properties内容如下:


book.name.placeholder=bookNamePlaceholder


@Component
// 引入自定义配置文件。
@PropertySource({"classpath:com/hry/spring/configinject/config.properties",
 // 引入自定义配置文件。${anotherfile.configinject}则是config.properties文件中的第二个属性值,会被替换为config_placeholder.properties。
   "classpath:com/hry/spring/configinject/config_${anotherfile.configinject}.properties"})
public class ConfigurationFileInject{
    @Value("${app.name}")
    private String appName; // 这里的值来自application.properties,spring boot启动时默认加载此文件
    @Value("${book.name}")
    private String bookName; // 注入第一个配置文件config.properties的第一个属性
    @Value("${book.name.placeholder}")
    private String bookNamePlaceholder; // 注入第二个配置外部文件属性
}
复制代码


5、切面(AOP)相关注解


在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程,简称AOP(aspect object programming)。AOP编程,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事物管理,日志记录等等。这些系统性的编程工作都可以独立编码实现,然后通过AOP技术切入进系统即可。从而达到了 将不同的关注点分离出来的效果。


aop技术的功能是让关注点与业务逻辑代码进行分离;而重复的代码就是关注点;关注点形成的类,就是切面(类)

Spring支持AspectJ的注解式aop编程,需要在java的配置类中使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持。下面介绍下aop编程的相关注解。


先说说@EnableAspectJAutoProxy注解,看看它的源码:


@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
    /**
     * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
     * to standard Java interface-based proxies. The default is {@code false}.
     */
    boolean proxyTargetClass() default false;
    /**
     * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
     * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
     * Off by default, i.e. no guarantees that {@code AopContext} access will work.
     * @since 4.3.1
     */
    boolean exposeProxy() default false;
}
复制代码


这里有两个方法,一个是控制aop的具体实现方式,为true 的话使用cglib,为false的话使用java的Proxy,默认为false,第二个参数控制代理的暴露方式,解决内部调用不能使用代理的场景,默认为false。


@Aspect:声明一个切面(类)上,作用是把当前类标识为一个切面供容器读取。


在切面类中需要定义切面方法用于响应响应的目标方法,切面方法即为通知方法,通知方法需要用注解标识,AspectJ 支持 5 种类型的通知注解:


@Before: 前置通知, 在方法执行之前执行
@After: 后置通知, 在方法执行之后执行 。
@AfterRunning: 返回通知, 在方法返回结果之后执行
@AfterThrowing: 异常通知, 在方法抛出异常之后
@Around: 环绕通知, 围绕着方法执行
复制代码


@PointCut :声明切点,是植入Advice(通知)的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是 public及void型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码


/**
 * 日志切面
 */
@Component
@Aspect
public class LoggingAspect {
    /**
     * 前置通知:目标方法执行之前执行以下方法体的内容 
     */
    @Before("execution(* com.qcc.beans.aop.*.*(..))")
    public void beforeMethod(JoinPoint jp){
        String methodName = jp.getSignature().getName();
        System.out.println("【前置通知】the method 【" + methodName + "】 begins with " + Arrays.asList(jp.getArgs()));
    }
    /**
     * 返回通知:目标方法正常执行完毕时执行以下代码
     */
    @AfterReturning(value="execution(* com.qcc.beans.aop.*.*(..))",returning="result")
    public void afterReturningMethod(JoinPoint jp, Object result){
        String methodName = jp.getSignature().getName();
        System.out.println("【返回通知】the method 【" + methodName + "】 ends with 【" + result + "】");
    }
    /**
     * 后置通知:目标方法执行之后执行以下方法体的内容,不管是否发生异常。
     * @param jp
     */
    @After("execution(* com.qcc.beans.aop.*.*(..))")
    public void afterMethod(JoinPoint jp){
        System.out.println("【后置通知】this is a afterMethod advice...");
    }
    /**
     * 异常通知:目标方法发生异常的时候执行以下代码
     */
    @AfterThrowing(value="execution(* com.qcc.beans.aop.*.*(..))",throwing="e")
    public void afterThorwingMethod(JoinPoint jp, NullPointerException e){
        String methodName = jp.getSignature().getName();
        System.out.println("【异常通知】the method 【" + methodName + "】 occurs exception: " + e);
    }
复制代码


总结


以上就是对spring中进行注解开发过程中使用到的一些注解的整理和介绍,spring中的注解还有很多,后续会继续更新其他的注解的一些使用,之前有文章也对这里说到的部分注解进行了详细的单篇文章的介绍,有兴趣的可以移步。

目录
相关文章
|
21天前
|
Java API 数据安全/隐私保护
掌握Spring Boot中的@Validated注解
【4月更文挑战第23天】在 Spring Boot 开发中,@Validated 注解是用于开启和利用 Spring 的验证框架的一种方式,特别是在处理控制层的输入验证时。本篇技术博客将详细介绍 @Validated 注解的概念和使用方法,并通过实际的应用示例来展示如何在项目中实现有效的数据验证
26 3
|
22天前
|
前端开发 Java 开发者
深入理解Spring Boot中的@Service注解
【4月更文挑战第22天】在 Spring Boot 应用开发中,@Service 注解扮演着特定的角色,主要用于标识服务层组件。本篇技术博客将全面探讨 @Service 注解的概念,并提供实际的应用示例,帮助开发者理解如何有效地使用这一注解来优化应用的服务层架构
78 1
|
22天前
|
Java 开发者 Spring
深入理解Spring Boot的@ComponentScan注解
【4月更文挑战第22天】在构建 Spring Boot 应用时,@ComponentScan 是一个不可或缺的工具,它使得组件发现变得自动化和高效。这篇博客将详细介绍 @ComponentScan 的基本概念、关键属性及其在实际开发中的应用。
30 4
|
23天前
|
Java 开发者 Spring
深入理解 Spring Boot 中的 @EnableAutoConfiguration 注解:概念与实践
【4月更文挑战第21天】在 Spring Boot 项目中,@EnableAutoConfiguration 注解是实现自动配置的核心,它可以根据项目的依赖和配置,自动地配置 Spring 应用程序中的 Bean
34 3
|
24天前
|
Java API 网络架构
深入理解 Spring Boot 中的 @RestController 注解:概念与实践
【4月更文挑战第20天】在现代Web开发中,创建RESTful服务已成为常态。Spring Boot通过提供@RestController注解,极大简化了REST API的开发过程。本篇博客旨在详细介绍@RestController的概念、优势以及在Spring Boot项目中的具体应用方法。
32 8
|
24天前
|
Java 开发者 Spring
Spring Framework 中的 @Autowired 注解:概念与使用方法
【4月更文挑战第20天】在Spring Framework中,@Autowired 注解是实现依赖注入(Dependency Injection, DI)的一种非常强大的工具。通过使用 @Autowired,开发者可以减少代码中的引用绑定,提高模块间的解耦能力
33 6
|
24天前
|
XML Java 数据库
探索 Spring Boot 中的 @Configuration 注解:核心概念与应用
【4月更文挑战第20天】在 Spring Boot 项目中,@Configuration 注解扮演了一个关键角色,它标识一个类作为配置源,这些配置用于定义和管理 Spring 应用程序中的 Bean
44 7
|
19天前
|
缓存 Java Sentinel
Springboot 中使用 Redisson+AOP+自定义注解 实现访问限流与黑名单拦截
Springboot 中使用 Redisson+AOP+自定义注解 实现访问限流与黑名单拦截
|
8天前
|
运维 Java 程序员
Spring5深入浅出篇:基于注解实现的AOP
# Spring5 AOP 深入理解:注解实现 本文介绍了基于注解的AOP编程步骤,包括原始对象、额外功能、切点和组装切面。步骤1-3旨在构建切面,与传统AOP相似。示例代码展示了如何使用`@Around`定义切面和执行逻辑。配置中,通过`@Aspect`和`@Around`注解定义切点,并在Spring配置中启用AOP自动代理。 进一步讨论了切点复用,避免重复代码以提高代码维护性。通过`@Pointcut`定义通用切点表达式,然后在多个通知中引用。此外,解释了AOP底层实现的两种动态代理方式:JDK动态代理和Cglib字节码增强,默认使用JDK,可通过配置切换到Cglib
|
4天前
|
JSON 前端开发 Java
【JAVA进阶篇教学】第七篇:Spring中常用注解
【JAVA进阶篇教学】第七篇:Spring中常用注解