Spring的IOC容器实例化bean的三种方式

2024-01-07 17:29:25
IOC容器实例化bean的三种方式:构造方法、静态工厂、实例工厂。
本文章涉及工程目录如下:

在这里插入图片描述

IOC容器实例化bean的三种方式

构造方法

对象在new的时候通过构造方法完成实例化。bean本质是对象,也可以通过构造方法完成实例化。

涉及代码片

// applicationContext.xml
<bean id="flowService" class="com.lwb.services.impl.FlowServiceImpl">
// FlowServiceImpl.java
public class FlowServiceImpl implements FlowService {
    private FlowServiceImpl(){
        System.out.println(this.getClass() + "-----进入FlowServiceImpl" +
                "无参构造器");
    }
    @Override
    public void saveService() {
        System.out.println(this.getClass() + "-----进入FlowServiceImpl");
    }
}
// App.java
public class App {
    public static void main(String[] args){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
}
执行后返回结果:

在这里插入图片描述
思考:
1、构造方法底层是通过反射机制实现的。注意上面无参构造方法是private,只有反射才能访问到私有方法。
2、底层使用的是无参构造方法。可以写一个带参的构造方法进行验证,会报错。

静态工厂

涉及代码片

// applicationContext.xml
<!--静态工厂实例化方法
        class为静态工厂类路径,factory-method 为方法名
    -->
    <bean id="flowDao1" class="com.lwb.factory.FlowDaoStaticFactory" factory-method="getFlowDao"/>
// FlowDaoStaticFactory.java
//注意getFlowDao是static的,所以叫静态工厂
public class FlowDaoStaticFactory {
     public static FlowDao getFlowDao(){
        System.out.println("-----进入静态工厂方法StaticFactory");
        return new FlowDaoImpl();
    }
}
// App.java
public class App {
    public static void main(String[] args){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
}
执行后返回结果:

在这里插入图片描述

思考:
1、为什么使用静态工厂方法,而不直接去new?
	静态工厂方法在返回new的对象实例之前,可以实现一些业务逻辑,如代码中的日志输出。

实例工厂

涉及代码片

// applicationContext.xml
	<bean id="flowDaoExFactory" class="com.lwb.factory.FlowDaoExFactory"/>
    <bean id="flowDao2" factory-method="getFlowDao" factory-bean="flowDaoExFactory"/>
// FlowDaoExFactory .java
//注意getFlowDao是public的,对比静态工厂
public class FlowDaoExFactory {
    public FlowDao getFlowDao(){
        System.out.println(this.getClass() + "------进入实例工厂类FlowDaoExFactory");
        return new FlowDaoImpl();
    }
}
// App.java
public class App {
    public static void main(String[] args){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
}
执行后返回结果:

在这里插入图片描述
思考:
1、静态工厂和实例工厂的区别?
静态工厂方法是static的,是在类加载的时候就创建了,可以直接使用,不需要实例化工厂类。实例工厂是public的,需要先实例化,才能使用。静态工厂适合实时性很高的场景。实际场景中大部分使用实例工厂。
2、实例工厂的简单写法——FactoryBean
涉及代码片

// applicationContext.xml
	<bean id="flowDao3" class="com.lwb.factory.FlowDaoFactoryBean"/>
// FlowDaoFactoryBean .java
public class FlowDaoFactoryBean implements FactoryBean<FlowDao> {
    //返回实例化对象
    @Override
    public FlowDao getObject() throws Exception{
        System.out.println(this.getClass() + "------进入实例工厂FlowDaoFactoryBean,getObject");
        return new FlowDaoImpl();
    }
    //返回class对象
    @Override
    public Class<?> getObjectType() {
        System.out.println(this.getClass() + "------进入实例工厂FlowDaoFactoryBean,getObjectType");
        return FlowDao.class;
    }
}
// App.java
public class App {
    public static void main(String[] args){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }
}

在这里插入图片描述
思考:
1、为什么只输出了getObject()里面的内容?getObject()重写了返回实例化对象的方法。getObjectType()返回的是class对象,只有在调用的时候才会执行(反射?)
2、FlowDaoFactoryBean可以通过重写isSingleton()方法声明是否是单例。

思考

1、上述例子中App.java为什么不获取bean(执行FlowDao flowDao = (FlowDao) ctx.getBean("flowDao3")),也能实例化?
IOC实例化bean对象的时机:
(1)IOC初始化的bean对象默认是单例的。单例+懒加载会在ioc容器初始化完成后直接实例化所有bean对象供使用。
(2)非单例和单例+非懒加载。在使用bean的时候才会去初始化。

文章来源:https://blog.csdn.net/weixin_43331454/article/details/135427735
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。