Java和Spring常用注解

8 篇文章 0 订阅

Bean标识

@component和@service

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

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

@Repository

用于标识一个类是 DAO(Data Access Object)组件。DAO 组件通常用于访问数据库或其他持久化存储机制,它们封装了对数据的访问和操作,提供了一种面向对象的方式来访问数据。

@Repository 注解本质上是 @Component 注解的一个特化版本,它们的作用是相同的。@Repository 注解的作用是为了更好地表达 DAO 组件的含义,使代码更加清晰易懂。

@Configuration

@Configuration主要用于标注一个Java类是Spring的配置类,Configuration注释类表明其主要目的是作为bean定义的源。
主要用法:
1.声明bean
在@Configuration类中使用@Bean注解,通过方法返回值来声明一个Bean,并将其加入到Spring容器中。

@Configuration
public class AppConfig {
    @Bean
    public MyBean myBean() {
        return new MyBean();
  }
}

@Configuration标记该类为配置类,@Bean标记myBean()方法返回的对象MyBean为Spring容器管理的组件。
2.引入配置

  • 使用@Import或注解,将其它配置类或配置文件中的bean加入到当前配置类中,以便在当前类中引用。
@Configuration
public class DatabaseConfig {
    @Bean
    public DataSource dataSource() {
        // 创建 DataSource Bean
    }
}

@Configuration
@Import(DatabaseConfig.class)
public class AppConfig {
    // 此处可以直接使用 DataSource:
    @Autowired
    DataSource dataSource;
  
    @Bean
    public MyBean myBean() {
        // 使用 DataSource 来创建 MyBean Bean
    }
}

DatabaseConfig 中定义了一个 DataSource 的 Bean,@Import 注解被用来将其引入到 AppConfig 中。这样,在 AppConfig 中可以直接使用 dataSource Bean。

  • 除了 @Import,我们还可以使用 @ImportResource 来引入其他 XML 文件中的配置。
@Configuration
@ImportResource({ "classpath:spring/context-config.xml", "classpath:spring/dao-config.xml" })
public class AppConfig {
    // ...
}
  • 使用 @Configuration 注解来标记这个类是一个配置类,然后使用 @Value 注解来从配置文件中读取相关的配置。
@Configuration
public class DataAccessConfig {

    @Value("${jdbc.driver-class-name}")
    private String driverClassName;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(dataSource());
    }

    @Bean
    public UserDao userDao() {
        return new UserDaoImpl(jdbcTemplate());
    }

    // 其他 DAO 相关 Bean 的定义
    // ...
}

@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()"属性,它可以被注入到对应的方法中。

Bean注入

@resource

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

@Resource
@Resource是Java标准注解,是JDK提供的,但是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 {

    @Resource
    private 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;
}

方法2: 在@Bean注解中指定Bean名称:

@Configuration
public class AppConfig {

    @Bean(name="userService")
    public UserService userService() {
        return new UserServiceImpl1();
    }

    @Bean(name="anotherUserService")
    public UserService anotherUserService() {
        return new UserServiceImpl2();
    }
}

@Resource的装配顺序:

  1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
  2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
  3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
  4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配。如果没有匹配,则回退为一个原始类型(UserDao)进行匹配,如果匹配则自动装配。(先Name后type)

Resource注解在字段上,这个注解是属于J2EE的,减少了与spring的耦合。可以指定是通过 name 还是 type 的注入方式,而@Autowired注解本身自己是不能实现这个效果的,要和@Qualifier一起用才可以!

@Autowired

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

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

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

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

public class TestServiceImpl() {
 
    @Autowired
    @Qualifier("userDaoImpl1")  // 指定哪一个实现类
    private UserDao userDao;
    ...   
}

方法2: @Primary
使用@Primary注解指定一个进行注入!!!

@Primary
@Mapper
public class UserDaoImpl01 implements UserDao {
    ...
}
@Mapper
public class UserDaoImpl02 implements UserDao {
    ...
}

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

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

Web MVC

@RequestMapping

将Web请求与请求处理类中的方法进行映射。
@RequestMapping注解拥有以下的六个配置属性:

  • value:映射的请求URL或者其别名
  • method:兼容HTTP的方法名
  • params:根据HTTP参数的存在、缺省或值对请求进行过滤
  • header:根据HTTP Header的存在、缺省或值对请求进行过滤
  • consume:设定在HTTP请求正文中允许使用的媒体类型
  • product:在HTTP响应体中允许使用的媒体类型
    提示:在使用@RequestMapping之前,请求处理类还需要使用@Controller@RestController进行标记
@controller
@RequestMapping(value=" /demo")
public class DemoController{
	@RequestMapping(value=" /home" ,method=RequestMethod.GET)
	public String home(){
		return "/home" ;
	}
}

@RequestMapping可以标记方法,也可以标记类。

@GetMapping是@RequestMapping(method=RequestMethod.GET)的快捷方式
@PostMapping是@RequestMapping(method=RequestMethod.POST)的快捷方式

@RequestBody

可以将请求主体中的参数绑定到一个对象中,此外,还可以通过@Valid注解对请求主体中的参数进行校验。

@RequestController
@RequestMapping("/api/v1")
public class UserController{
	@Autowired
	private UserService userService;
	@PostMapping("/users")
	public User createUser@Valid @RequestBody User user){
		return userService.save(user);
	}

@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;
    }
 
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
 
    @Override
    public 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);
    }
 
    @Override
    public 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属性了。

@Profile

Java @Profile是Spring框架中所提供的一种条件注解。通过使用@Profile注解,可以为不同的环境(例如开发环境和生产环境)配置不同的bean。

使用@Profile注解需要以下两个步骤:

  1. 标记bean:在需要标记的类或方法上添加@Profile注解,并指定其所属的环境,例如@Profile("dev")注解表示该类或方法为开发环境下的bean。

  2. 激活配置:在Spring的配置文件中,通过指定激活的环境,从而加载对应环境下的配置。例如,使用spring.profiles.active属性指定运行环境为开发环境:-Dspring.profiles.active=“dev”。

在Spring Boot中,可以通过在application.properties或application.yml文件中设置spring.profiles.active属性来激活对应的配置文件。例如,当spring.profiles.active属性设置为"dev"时,Spring Boot会加载application-dev.properties或application-dev.yml配置文件中的配置信息。

通过使用@Profile注解,可以使开发者轻松地将不同的bean和配置文件分离,并为不同的环境提供不同的配置信息,从而提高应用程序的可配置性和可移植性。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值