Bean实例化三种方法

今天刚学到bean的构造方法,就把自己的笔记分享到CSDN

方法一:构造方法

先给出代码:

public class UserDaoImpl implements UserDao {

    //可省略
    public UserDaoImpl(){
        System.out.println("bean实例化之构造方法");
    }
    @Override
    public void save() {
        System.out.println("bean成功实例化");
    }
}

不使用spring创建对象:

public class APP2 {
    public static void main(String[] args) {

        UserDao userDao = new UserDaoImpl();
        userDao.save();
        
    }
}

使用spring创建对象:

xml配置文件:

<!--    实例化bean之构造方法-->
    <bean id="userDao" class="org.example.dao.impl.UserDaoImpl"></bean>

使用spring创建对象:

public class APP2 {
    public static void main(String[] args) {

//        UserDao userDao = new UserDaoImpl();
//        userDao.save();

        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserDao  userDao = (UserDao) app.getBean("userDao");

        userDao.save();
    }
}

运行结果:

 方法二:静态工厂

先创建工厂类

public class UserDaoFactoryStatic {
    public static UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

不使用spring创建对象:

public class APP2 {
    public static void main(String[] args) {

//        静态工厂
        UserDao userDao = UserDaoFactoryStatic.getUserDao();
        userDao.save();

    }
}

使用spring创建对象

配置xml文件:

注意这里class创建的是UserDaoFactoryStatic的bean对象,所以我们需要factory-method来调用方法创建userDaoImpl的bean对象

<!--    实例化bean之静态工厂-->
    <bean id="userDao" class="org.example.factory.UserDaoFactoryStatic" factory-method="getUserDao"></bean>

方法三:实例工厂

复杂版:

先创建实例工厂

public class UserDaoFactory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

不使用spring创建对象:

由于UserDaoFactory不是静态,所以要想调用getUserDao方法得先创造UserDaoFactory对象

public class APP2 {
    public static void main(String[] args) {

//        实例工厂
        UserDaoFactory userDaoFactory = new UserDaoFactory();
        UserDao userDao = userDaoFactory.getUserDao();
        userDao.save();

    }
}

使用spring创建对象:

xml文件配置

<!--    实例化bean之实例工厂复杂版-->
<!--        先创建userDaoFactory的bean对象-->
        <bean id="userDaoFactory" class="org.example.factory.UserDaoFactory"></bean>
<!--        再创建userDao的bean对象-->
        <bean id="userDao" factory-bean="userDaoFactory" factory-method="getUserDao"></bean>

咋一看感觉使用spring更加麻烦了,而且每次都要先创建工厂的bean,于是spring出于人性化就给了FactoryBean接口让我们更简易的操作

简易版

重新创建实例工厂,实现FactoryBean接口

public class UserDaoFactoryBean implements FactoryBean<UserDao> {

    @Override
    public UserDao getObject() throws Exception {
        System.out.println(this);
        return new UserDaoImpl();
    }

    @Override
    public Class<?> getObjectType() {
        System.out.println(UserDao.class);
        return UserDao.class;
    }
}

xml配置文件:

<!--    实例化bean之实例工厂简易版-->
    <bean id="userDao" class="org.example.factory.UserDaoFactoryBean"></bean>

如何理解FactoryBean的两个方法呢?

可以看到xml配置里创建的是UserDaoFactoryBean的对象

 我的理解是配置里创建了UserDaoFactoryBean的bean对象,然后配置自动扫描UserDaoFactoryBean类,第一个方法返回的是工厂创建bean的对象方法;

第二个方法是返回字节码文件,返回给xml配置文件我们要实例化bean的地址信息。

最后

三种方法的测试对比。

public class APP2 {
    public static void main(String[] args) {
//    普通方法实现

//        实例工厂
//        UserDaoFactory userDaoFactory = new UserDaoFactory();
//        UserDao userDao = userDaoFactory.getUserDao();
//        userDao.save();

//        静态工厂
//        UserDao userDao = UserDaoFactoryStatic.getUserDao();
//        userDao.save();

//        构造方法
//        UserDao userDao = new UserDaoImpl();
//        userDao.save();

//Spring方法实现

        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserDao  userDao = (UserDao) app.getBean("userDao");

        userDao.save();
    }
}

可以看到spring方法简化了我们测试代码,三种方法都是一样的代码,但需要我们在xml文件里配置bean

ClassPathXmlApplicationContext获取我们xml文件

getBean()是入口,指向的是bean标签的id,找到了id就可以找到对应的类进行对象的创建。

xml配置文件:

id:bean的id,使用容器可以通过id值获取对应的bean,在一个容器中id值唯一

class:bean的类型,即配置的bean的全路径类名

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


<!--    实例化bean之构造方法-->
<!--    <bean id="userDao" class="org.example.dao.impl.UserDaoImpl"></bean>-->

<!--    实例化bean之静态工厂-->
<!--    <bean id="userDao" class="org.example.factory.UserDaoFactoryStatic" factory-method="getUserDao"></bean>-->

<!--    实例化bean之实例工厂复杂版-->
<!--        先创建userDaoFactory的bean对象-->
<!--        <bean id="userDaoFactory" class="org.example.factory.UserDaoFactory"></bean>-->
<!--        再创建userDao的bean对象-->
<!--        <bean id="userDao" factory-bean="userDaoFactory" factory-method="getUserDao"></bean>-->

<!--    实例化bean之实例工厂简易版-->
    <bean id="userDao" class="org.example.factory.UserDaoFactoryBean"></bean>

</beans>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这道题要求介绍三种方式来实例化 bean,并比较这三种方式的异同之处。 可能的回答如下: 三种实例化 bean 的方式分别是:构造方法注入、 setter 方法注入以及静态工厂方法注入。 构造方法注入是指在 bean 的定义中通过构造方法传入依赖,如: ```xml <bean id="userDao" class="com.example.UserDao"> <constructor-arg ref="sessionFactory" /> <constructor-arg ref="transactionManager" /> </bean> ``` 这里,`UserDao` 类的构造方法需要一个 `SessionFactory` 对象和一个 `TransactionManager` 对象作为参数。在 `bean` 的定义中,我们用 `constructor-arg` 元素传入这两个对象的引用。这样一来,当容器创建 `userDao` 实例时,会自动将这两个引用注入到 `UserDao` 的构造方法中。 setter 方法注入类似,但是是通过 setter 方法传入依赖,如: ```xml <bean id="userService" class="com.example.UserService"> <property name="userDao" ref="userDao" /> </bean> ``` 这里,`UserService` 类有一个 `UserDao` 对象的 setter 方法 `setUserDao`,我们用 `property` 元素指定要设置的属性名和引用。这样一来,当容器创建 `userService` 实例时,会自动将 `UserDao` 的实例注入到 `UserService` 中。 静态工厂方法注入是指使用静态方法创建 bean 对象,如: ```xml <bean id="foo" class="com.example.Foo" factory-method="getInstance"> <constructor-arg value="foo" /> </bean> ``` 这里,`Foo` 类定义了一个静态方法 `getInstance`,用于创建 `Foo` 实例。在 `bean` 的定义中,我们用 `factory-method` 属性指定要使用的静态方法。这样一来,当容器创建 `foo` 实例时,会调用 `getInstance` 方法创建 `Foo` 对象。 三种方式之间的异同主要在于注入方式不同,但其实它们最终都达到了相似的效果,即将依赖注入到 bean 中,让 bean 可以使用这些依赖。选择哪种方式,主要取决于具体情况。通常来说,构造方法注入更适合必要的依赖,而 setter 方法注入更适合可选的依赖或者需要动态变更的依赖。工厂方法注入则更适合复杂的创建过程或者需要缓存创建的对象。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值