> 文章列表 > Java和Spring常用注解

Java和Spring常用注解

Java和Spring常用注解

@component和@service

在Spring框架中,@Component和@Service都是用来将一个Java类标记为Spring容器中的一个组件。不过,在实际开发中,@Service通常用于标记业务层的Bean,而@Component则更为通用,可以用于标记任意层的Bean。

具体而言,@Component表示通用的组件,可以用在任何层次。它是一个比较抽象的概念,可以用于标记任何需要被Spring容器管理的组件类。而@Service则表示服务层组件,用于标记服务层(业务层)的Bean。所以,@Service通常和@Repository(用于标记DAO层数据访问对象)一起使用,一起组成完整的MVC架构中的三层结构。

@resource和@autowird

在Spring框架中,@Resource和@Autowired都可以用于将一个Bean注入到另一个Bean中,不过它们有一些区别。

@Resource
@Resource是Java标准注解,也被Spring框架支持,可以用来注入其他Bean,它是按照名称进行自动装配的。它提供了两个属性:name和type。

当使用name属性时,它会按照指定的名称查找对应的Bean进行注入;当使用type属性时,它会按照指定的类型查找对应的Bean进行注入。

@Service("userService")

当@Resource注解需要装配的Bean在容器中有多个与之对应的Bean名称时,会抛出NoSuchBeanDefinitionException异常。
例如,假设有两个实现UserService接口的类:

@Service("userService1")
public class UserServiceImpl1 implements UserService {
}@Service("userService2")
public class UserServiceImpl2 implements UserService {
}

在另一个需要依赖一个UserService的类中,如果使用@Resource注解进行注入:

@Service
public class SomeServiceImpl implements SomeService {@Resourceprivate UserService userService;
}

在尝试装配UserService时,由于容器中存在多个与之对应的Bean名称,会抛出NoSuchBeanDefinitionException异常。此时,我们需要使用@Qualifier注解或者在@Bean注解中指定Bean名称来解决装配冲突。

  1. 使用@Qualifier注解指定具体的Bean名称:
@Service
public class SomeServiceImpl implements SomeService {@Resource@Qualifier("userService1")private UserService userService;
}

@Service
public class SomeServiceImpl implements SomeService {@Resource(name="userService")private UserService userService;
}
  1. 在@Bean注解中指定Bean名称:
@Configuration
public class AppConfig {@Bean(name="userService")public UserService userService() {return new UserServiceImpl1();}@Bean(name="anotherUserService")public UserService anotherUserService() {return new UserServiceImpl2();}
}

@Autowired
@Autowired是Spring框架特有的注解,也是按照类型进行自动装配的。它默认按照类型查找对应的Bean,并将它注入到需要依赖的Bean中。如果有多个同一类型的Bean存在,它还可以使用Qualifier注解指定需要注入的Bean名称。

更具体地说,当一个Bean中出现了@Autowired注解,容器会自动完成以下步骤:

  1. 搜索容器中所有匹配于指定类型的Bean;
  2. 如果只找到一个与指定类型匹配的Bean,则将此Bean自动注入到当前需要的Bean中;
  3. 如果找到多个与指定类型匹配的Bean,则从中选择一个合适的Bean自动注入。

同样,当@Autowired注解需要装配的Bean在容器中有多个与之对应的Bean类型时,Spring会尝试按类型进行自动装配。如果根据类型无法确定要装配哪个Bean时,会抛出NoUniqueBeanDefinitionException异常。此时,我们需要使用@Qualifier注解或者在@Bean注解中指定Bean名称来解决装配冲突。

区别
与@Resource不同,@Autowired是Spring框架特有的注解,而且它可以使用更加灵活的方式进行关联。@Autowired是按照类型进行自动装配的,可以与Qualifier注解一起使用进行名称匹配,并且它支持@Primary注解,用于指定默认的Bean。此外,@Autowired注解还支持使用构造函数注入、Setter方法注入、成员变量注入等不同的方式。

而@Resource则是Java标准注解,虽然它也可以进行自动装配,但只支持按照名称和类型查找Bean,并且它没有像@Autowired那样支持更加灵活的@Autowired注释组合操作。

@interface

Java中的@interface是用于声明注解的关键字。注解是Java语言提供的一种元数据机制,它可以提供给代码的编写者和阅读者更多的信息,也可以标识代码中特定的语义。

使用@interface关键字声明的注解本质上是一种特殊的接口定义,它可以包含属性、方法、默认值等信息。注解可以被应用于类、方法、字段和其他元素上,通过注解的方式对这些元素进行标记,随后可以在编译时、类加载时、运行时等各种时期通过反射机制读取注解信息,从而实现对代码的一些非侵入式操作。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {String value();
}public class MyClass {@MyAnnotation("Hello World")public void sayHello() {System.out.println("Hello World");}
}

在该例子中,自定义了一个注解MyAnnotation,在MyClass中的sayHello方法上使用了该注解。这里的注解可以提供一些有用的元数据,如"value()"属性,它可以被注入到对应的方法中。

@Data,@Setter和@Getter

@Data注解是Lombok提供的一个注解,它会自动为类生成一些常用方法,如@Getter、@Setter、@ToString、@EqualsAndHashCode和@RequiredArgsConstructor等,它们的作用如下:

@Getter和@Setter注解会自动生成属性的get和set方法,使得我们在使用属性时不需要手动编写这些方法。
@ToString注解会自动生成toString方法。
@EqualsAndHashCode注解会自动生成equals和hashCode方法。
@RequiredArgsConstructor注解会自动生成一个包含所有final和@NonNull属性的构造方法。
而使用@Getter和@Setter注解则只会自动生成get和set方法,不能自动生成其他方法,如@ToString、@EqualsAndHashCode和@RequiredArgsConstructor等。
例如下面的代码:

@Data
public class Person {private String name;private int age;
}

使用@Data注解可以等价于以下代码:

public class Person {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age && Objects.equals(name, person.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}public Person(String name, int age) {this.name = name;this.age = age;}
}

@EqualsAndHashCode

@EqualsAndHashCode是Lombok提供的一个注解,可以自动为类生成equals和hashCode方法。equals和hashCode方法是用于判断对象是否相等和将对象插入散列表中时的重要方法,通过使用@EqualsAndHashCode注解可以避免手动重写equalshashCode方法。

@EqualsAndHashCode注解默认对所有属性进行比较,如果只想对某些属性进行比较,也可以使用exclude和of属性来指定,比如:

@Data
@EqualsAndHashCode(exclude = "id")
public class User{private Long id;private String name;private Integer age;
}

这样,equals和hashCode方法就会忽略id属性,只比较name和age属性了。