Spring学习笔记(三)注解开发

注解开发

之前介绍的所有方法都是在xml文件中手动配置每一个需要的bean,spring提供了注解方式,不需要在xml中再详细写每一个bean,可以直接为bean对应的java类添加注解,使之成为bean对象,并在xml文件中告诉框架即可。

定义Bean

首先需要在pom.xml中添加spring-context依赖才可以使用@Component注解:

 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-context</artifactId>
     <version>5.3.19</version>
     <scope>compile</scope>
 </dependency>

在java类中添加注解:

 @Component("bookService")
 public class BookServiceImpl implements BookService {}

核心配置文件xml中通过组件扫描加载bean,spring会识别指定package下所有带@Component注解的实体类。

 <context:component-scan base-package="com.yuan"/>

tips: spring为了区分不同bean的作用,提供了三个衍生注解,和@Component租用完全一样,不一样的是可以直接通过注解名字看出功能。

  • @Controller 用于表现层bean定义
  • @Service 用于业务层bean定义
  • @Repository 用于数据层bean定义

纯注解开发

核心配置文件applicationContext.xml也可以使用注解方式配置,过程如下:

1.新建配置文件SpringConfig.java,@Configuration注解用于设定当前类为配置类(代替了applicationContext.xml),而@ComponentScan注解用于设定扫描路径,代替了原配置文件中的context:component-scan标签内容,若有多个路径,则需要用数组格式{"path_a","path_b"}

 @Configuration
 @ComponentScan("com.yuan")
 public class SpringConfig {
 }

2.此时获取ApplicationContext(即IoC容器)的方式也发生了改变:

 //方法参数为配置文件类
 ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
 Object obj = ctx.getBean("id");

管理Bean的生命周期

用注解方式管理bean的生命周期,只需要在对应方法添加注解即可,如下:

 @PostConstruct
 public void init(){
     System.out.println("init bookdaoimpl");
 }
 ​
 @PreDestroy
 public void destroy(){
     System.out.println("destroy bookdaoimpl");
 }

依赖注入自动装配⭐

直接在类中为需要注入的对象添加注解@Autowired,表示按类型自动装配,此时不再需要set方法;@Qualifier注解表示指定按名称装配,不需要时可以不写。

 //引用类型注入
 @Autowired
 @Qualifier("bookDao")
 private BookDao bookDao;
 //简单类型注入
 @Value("zs")
 private String name;

tips:

  • ⭐自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法;
  • 自动装配建议使用无参构造方法创建对象

至于简单类型为什么不直接赋值而是使用注解,有时候它的值不是写死的,具体值可能来自于外部,例如来自于properties文件,则加载参数时需要:

1.配置类中添加注解@PropertySource

 @Configuration
 @PropertySource("jdbc.properties")
 @ComponentScan("com.yuan")
 public class SpringConfig {
 }

2.bean相关类中的简单类型注入方式可以改为${}

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

第三方Bean管理

之前通过核心配置文件管理第三方bean时,只需要在引入第三方依赖后直接配置使用bean即可,但通过注解方式管理的话,因为不能直接修改第三方代码,所以需要自己手动编写代码管理和注入依赖。

在配置文件中添加方法,通过手动调用set方法进行依赖注入:

 @Configuration
 public class SpringConfig{
     @Bean
     public DataSource dataSource(){
         DruidDataSource ds = new DruidDataSource();
         ds.setDriverClassName();
         ds.setUrl();
         ds.setUsername();
         ds.setPassword();
         return ds;
     }
 }

这样写倒是能实现功能,但是有个问题:JDBC的配置和Spring的Bean配置写在一起了,不够清晰,因此我们把JDBC的配置单拎出来,在SpringConfig中加入关联即可:

 //JDBC类文件(类不需要加注解)
 public class JdbcConfig{
     @Bean
     public DataSource dataSource(){...}
 }
 ​
 //SpringConfig类文件
 //采用导入方式加入配置类到核心配置文件,多个文件用数组方式{}
 @Configuration
 @Import(JdbcConfig.class)
 public class SpringConfig{
 }

第三方bean依赖注入

简单类型:直接新建参数,添加@value注解即可;

引用类型:写入方法的形参,容器会根据类型自动装配对象。

自定义bean和第三方bean对比

自定义Bean第三方Bean
定义Bean的注解方式@Component @Controller @Service @Repository@Bean @Configuration/@import(XXConfig.class)
依赖注入简单类型@Value() 引用类型@Autowired @Qualifier(“id”)简单类型@Value() 引用类型:构造方法形参(不全是吧)

关于引用类型依赖注入的不同方式(@Autowired和构造方法形参)使用场景:

通常使用@Autowired自动装配,但若以下情况,建议使用构造方法形参:

  • 类中有多个依赖需要注入,且这些依赖是必须的,不能为null(避免空指针异常)
  • 类中依赖关系复杂,需要多层嵌套,使用构造方法可以保证依赖关系的正确性,避免手动注入可能造成的错误
  • 需要对依赖进行初始化操作时,使用构造方法注入,这样可以在初始化实例对象时,将依赖对象初始化。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注