2.3 Spring4 快速入门-bean 的注入与初始化和销毁

本文介绍Spring框架下Bean的三种初始化和销毁方式,包括实现InitializingBean和DisposableBean接口、使用@PostConstruct和@PreDestroy注解,以及在@Bean定义中指定initMethod和destroyMethod。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本章写的主要是bean的三种初始化与注销方式及几个注解组件。
初始条件:
1. Java version : 1.8
2. maven version : 1.3.9
3. IDE: IDEA

第1步: 创建简单形式的 Maven 工程(quick starter)。
第2步:在 POM 文件中加入 Spring5 的依赖。

 <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.0.RELEASE</version>
 </dependency>

第3步: 创建 User 类作为 bean,加上 @Component 作为 Spring 的一个组件。

import org.springframework.stereotype.Component;

@Component
public class User {
private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
 }

第4步: 创建主类 App (含有main的可执行程序),加上@ComponentScan,让 Spring 自动去扫描当前包及其子包里面带有 @Component @Configuration 等注解的类,并加载为组件(bean).

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan
public class App 
{
    public static void main( String[] args )
    {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(App.class);
        System.out.println(ctx.getBean(User.class));
        System.out.println("User ID --- > " + ctx.getBean(User.class).getId());
        ctx.close();
    }
}

此时 User 类并没有初始化,运行程序输出的是:

com.test.User@58fdd99
User ID --- > null

bean 的初始化及销毁方式一

使 User 类继承 Spring 自带的初始化与销毁组件 InitializingBean(初始化),DisposableBean(销毁),并继承其方法。

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class User implements InitializingBean,DisposableBean{
private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
    /* User bean 初始化操作 */
    public void afterPropertiesSet() throws Exception {
        System.out.println("<--------User bean 初始化-------->");
        id = "ID_0000001";
    }
    /* User bean 销毁操作 */
    public void destroy() throws Exception {
        System.out.println("<--------User bean 销毁-------->");
    }
}

在上面的初始化代码中,使 User.id 初始化为 id=“ID_0000001”,运行程序的结果是:

<--------User bean 初始化-------->
com.test.User@709ba3fb
User ID --- > ID_0000001
<--------User bean 销毁-------->

bean 的初始化及销毁方式二

只需要修改上面的 User 类,使用 @PostConstruct(初始化)
@PreDestroy (销毁)注解声明方法。

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
public class User {
private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    /* 初始化方法 */
    @PostConstruct
    public void init() throws Exception {
        System.out.println("<--------User bean 初始化-------->");
        id = "ID_0000001";
    }

    /* 销毁方法 */
    @PreDestroy
    public void destroy() throws Exception {
        System.out.println("<--------User bean 销毁-------->");
    }
}

运行主类 App 结果输出:

<--------User bean 初始化-------->
com.test.User@525b461a
User ID --- > ID_0000001
<--------User bean 销毁-------->

bean 的初始化及销毁方式三

  1. 修改 User 类:
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
public class User {
private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void init() throws Exception {
        System.out.println("<--------User bean 初始化-------->");
        id = "ID_0000001";
    }

    public void destroy() throws Exception {
        System.out.println("<--------User bean 销毁-------->");
    }
}
  1. 新建 UserConfig 配置类,在声明 bean 时指定 User 的初始化与销毁方法。
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class UserConfig {

    @Qualifier("getUser")
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public User getUser(){
        return new User();
    }
}
  1. 修改 App 主类:
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
public class App 
{
    public static void main( String[] args )
    {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(App.class);

        System.out.println("UserConfig --- > " + ctx.getBean(UserConfig.class).getUser().getId());
        System.out.println("User ID --- > " + ctx.getBean("getUser"));

        ctx.close();
    }
}

结果输出:

<--------User bean 初始化-------->
UserConfig --- > ID_0000001
User ID --- > com.test.User@145eaa29
<--------User bean 销毁-------->


@Component、@Repository、@Service、@Controller
的作用都是将类标识为 bean 。只是它们在应用时用在不同的地方,已做层次上的区分。
Component : 用于普通的类。
Repository : 用于 dao 层。
Service : 用于service 层。
Controller : 用于 Controller。

  1. Repository 示例:
import org.springframework.stereotype.Repository;

@Repository  
public class UserDao {
}
  1. Service 示例:
import org.springframework.stereotype.Service;
@Service
public class UserService {
}
  1. Controller 示例:
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
}

注入bean,使用 Autowired  / Resource(JSR-250) / Inject (JSR-330 ,需要额外添加javax.inject 依赖) 

  1. 在 Controller 中 注入 Service :
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    @Autowired
    private UserService userService;
}
  1. 在 Service 中 注入 Dao :
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Autowired
    private UserDao userDao;
}

可能存在的问题

Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.test.User' available: expected single matching bean but found 2: user,getUser

在注入 bean 的时候可能提示存在多个相同类型的bean,此时可以使用 @Primary 声明目标bean,这个注解的意思是,如果系统找到多个相同类型的bean,会首先来取有Primary  声明的bean,用来解决存在bean的注入失败问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值