Java Spring创建bean流程及自定义构造方法示例

发布于:2024-03-29 ⋅ 阅读:(20) ⋅ 点赞:(0)

一、spring容器创建bean的简单步骤
1、扫描被@Service,@Component等注解标识的类。
2、找到类的构造方法
默认使用无参构造方法构建bean,如果类中定义了有参构造方法则会按照有参构造方法构建bean。
3、依赖注入
如果类中存在@Autowired或有参的构造方法,会先从单例池获取对象,如果单例池没有对象则会创建对象,之后在放入单例池中 。如果有构造方法,会在注入完成后去执行该方法,进行一些属性的配置等。
4、执行spring的其他机制
(1)、实现aware类型的接口则会去执行相对应的set方法;
(2)、实现InitializingBean接口则会执行对应afterProperties方法;
(3)、系统定义了实现BeanPostProcessor接口的类,会在创建每一个bean之前执行(postProcessBeforeInitialization)和之后执行(postProcessAfterInitialization)方法等等。
5、使用bean
(1)、使用@Autowired,@Resource注解注入
(2)、被扫描的类存在构造方法,构造方法参数中获取bean。常用于当前bean的其他属性赋值。

二、自定义构造方法创建bean代码示例
1、创建统一的出售服务SailService

import com.zw.study.springBean.dto.Fruit;
public interface SailService {
    String getFruitType();   // 定义类型,用于区分实现类
    void addOrder(Fruit fruit);
}

2、实例化苹果和梨的SailService

// 苹果的实现类
import com.zw.study.springBean.dto.Fruit;
import com.zw.study.springBean.service.SailService;
import org.springframework.stereotype.Service;
@Service
public class AppleSailServiceImpl implements SailService {
    @Override
    public String getFruitType() {
        return "apple";
    }
    @Override
    public void addOrder(Fruit fruit) {
        System.out.println("新增苹果的订单");
    }
}

// 梨子的实现类
import com.zw.study.springBean.dto.Fruit;
import com.zw.study.springBean.service.SailService;
import org.springframework.stereotype.Service;
@Service
public class PearSailServiceImpl implements SailService {
    @Override
    public String getFruitType() {
        return "pear";
    }
    @Override
    public void addOrder(Fruit fruit) {
        System.out.println("新增梨子的订单");
    }
}

3、订单服务根据业务类型选择不同Service去执行(自定义构造方法)

import com.zw.study.springBean.dto.Fruit;
import com.zw.study.springBean.service.SailService;
import com.zw.study.springBean.service.FruitService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Service
public class FruitServiceImpl implements FruitService {

    // 所有销售服务的封装Map
    private Map<String, SailService> fruitSailServiceMap = new HashMap<>();
    
    // 说明:本例中因为SailService有多个实现类,需要区分业务在不同情况下选择不同的类去执行,所以不能直接通过@Autowired去注入SailService服务,所以这里需要创建Map将所有的SailService都获取到,之后业务在根据自己的需要选择Service去执行。
    // 这里的Map是FruitServiceImpl的一个属性。本例通过指定带参的构造方法去封装属性。spring容器在加载FruitServiceImpl这个bean的时候通过这个有参的构造方法去创建实例,之后在这个构造方法中去封装属性Map
    // 注意:如果没有指定任何构造方法的话,java会默认提供一个无参的构造方法,但是指定了就不会有默认的构造方法了。
    // 参数SailService[],容器会在创建该bean的时候,从spring容器的单例池去获取,如果不存在则会先创建之后在放入单例池中
    public FruitServiceImpl(SailService[] sailServices){
        for (SailService sailService : sailServices){
            String fruitType = sailService.getFruitType();
            if (!fruitSailServiceMap.containsKey(fruitType)){
                fruitSailServiceMap.put(fruitType, sailService);
            }
        }
    }
    @Override
    public void sailFruit(Fruit fruit) {
        // 根据参数指定的类型,选择对应的销售服务去创建订单
        SailService sailService = getSailServie(fruit);
        sailService.addOrder(fruit);
    }
	// 根据类型获取指定的业务处理服务
    private SailService getSailServie(Fruit fruit) {
        String type = fruit.getType();
        return fruitSailServiceMap.get(type);
    }
}

4、测试验证
参数传不同的类型
在这里插入图片描述
在这里插入图片描述

以上完成了通过自定义构造方法,实例化bean的过程。常用于:
1、一个通用接口,有多个实例对象的场景
2、创建bean时封装bean的属性

附:
BeanPostProcessor:
是Spring框架中非常强大的一个接口,它允许开发者在Spring容器创建和初始化Bean的过程中插入自定义的逻辑。亲测会在每一个bean创建的过程中都会被调用一次,因此业务需要梳理清晰,不要做很多无畏的操作。可以在此方法中设置bean的属性,或者配合自定义注解完成一些特俗业务等。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
	// bean创建之前执行 
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("**Before Initialization****: " + beanName);
        return bean; // 返回原bean或修改后的bean
    }
    // bean创建之后执行 
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("**After Initialization****: " + beanName);
        return bean; // 返回原bean或修改后的bean
    }
}

学海无涯苦作舟!!!

本文含有隐藏内容,请 开通VIP 后查看