Spring学习-IOC容器怎样创建对象

1.IOC容器创建对象的原理

        我们知道Spring创建对象是在xml文件中使用bean标签创建的,当我们获取上下文对象时就会被创建(下面会讲到),那么为什么Spring使用bean标签就能创建一个对象呢?

        通常我们在new一个对象时会调用这个类的构造器,即使我们在编写一个类时不写构造方法,系统也会生成一个默认的无参构造方法,这个无参构造方法实际上继承的是万类之父Object的无参构造方法,所以即使我们不写构造函数也能直接new创建。那么当我们写了自己的无参构造方法后,new一个对象就会调用我们自己写的无参构造方法,这就是重写构造函数。

        既然new是调用的构造器来创建,那么bean标签是不是也是通过调用的构造器来创建对象呢?我们来做一个实验,使用bean标签创建一个User对象:

        先定义一个User类:

public class User {
    
    private String name;
    private int age;
    
    //重写无参构造,如果调用了无参构造就会输出“调用了构造函数”
    public User() {
        System.out.println("调用了构造函数");
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }
}

        然后通过bean标签创建一个user对象:

    <!--创建一个User类对象,并给name和age属性赋值-->
    <bean id="user" class="com.anzekun.pojo.User">
        <property name="name" value="zhangsan"/>
        <property name="age" value="20"/>
    </bean>

        最后通过使用getBean方法让Spring开始创建来测试是否调用了重写的构造方法:

public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        User user= (User) context.getBean("user");
    }

        运行结果:

        由此可见,Spring容器使用bean标签来创建对象,实际上是调用了构造器创建的,这就是IOC容器创建对象的原理。

2.使用bean标签实现有参构造

        上面我们使用的是无参构造方法,并利用set方法给user的属性赋值(property标签给属性赋值就是调用的set方法,即使用set方法进行依赖注入),那么怎样进行有参构造呢?Spring也为我们提供了有参构造的bean标签创建对象的方法,并且有三种:

        先写一个有参构造器:

//有参构造
    public User(String name,int age){
        this.name=name;
        this.age=age;
    }

        测试:

public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        User user= (User) context.getBean("user");
        System.out.println("name:"+user.getName());
        System.out.println("age:"+user.getAge());
    }
  •  第一种,使用下标赋值
    <!--利用下标赋值-->
    <bean id="user" class="com.anzekun.pojo.User">
        <!--0代表第一个参数,1代表第二个参数-->
        <constructor-arg index="0" value="zhangsan"/>
        <constructor-arg index="1" value="15"/>
    </bean>

        运行结果:

  • 第二种,使用参数类型赋值
    <!--使用参数类型赋值-->
    <bean id="user" class="com.anzekun.pojo.User">
        <constructor-arg type="java.lang.String" value="lisi"/>
        <constructor-arg type="int" value="20"/>
    </bean>

        运行结果:

        不过要注意的是,由于这种方法是利用参数类型区分参数的,所以如果有多个相同类型的参数不建议使用这种方法

  • 第三种,使用参数名赋值
    <!--使用参数名赋值-->
    <bean id="user" class="com.anzekun.pojo.User">
        <constructor-arg name="name" value="wangwu"/>
        <constructor-arg name="age" value="19"/>
    </bean>

        运行结果:

3.IOC容器创建对象是一次创建所有对象还是用到哪个才创建哪个?

        我们先获取两个对象,观察是否调用了构造函数:

    <!--创建两个对象-->
    <bean id="user" class="com.anzekun.pojo.User">
        <property name="name" value="zhangsan"/>
        <property name="age" value="20"/>
    </bean>
    <bean id="user1" class="com.anzekun.pojo.User">
        <property name="name" value="lisi"/>
        <property name="age" value="15"/>
    </bean>

        使用之前的无参构造函数进行测试,如果调用了构造函数就输出“调用了构造函数”:

       

    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        System.out.println("获取第一个对象");
        User user= (User) context.getBean("user");
        System.out.println("获取第二个对象");
        User user1=(User) context.getBean("user1");
    }

        运行结果:

        从运行结果可以看出,我们在获取对象之前就调用了两次构造函数,这就说明当我们在获得Spring的上下文对象时Spring就已经创建好了所有的对象,后面我们获取的时候直接拿就行了,这也就是为什么叫做容器的原因了

4.如果两次获取同一个id的对象,这两个对象是否是同一个对象?

        上面我们进行的测试结果是先创建所有的对象,后面获取时不会再创建,对于这个问题我们大致也能猜到这两个是同一个对象了,来看测试:

        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        //两次获取同一个id对象
        User user= (User) context.getBean("user");
        User user1= (User) context.getBean("user");
        //输出比较结果
        System.out.println(user1==user);

        运行结果:

        所以同一个id的对象Spring只会创建一个,每次获取的都是同一个对象

  • 14
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring-IOCSpring框架的核心部分之一,它是一种设计模式,全称为Inversion of Control(控制反转)。它通过将对象的创建、依赖关系的管理和对象的生命周期交给Spring容器来实现,从而降低了组件之间的耦合度,提高了代码的可重用性和可维护性。Spring-IOC的实现主要依靠Spring容器Spring容器Spring框架的核心,它负责创建、管理和装配Bean对象,其Bean是Spring框架最基本的组件。 Spring-IOC的实现主要有两种方式:BeanFactory和ApplicationContext。其,BeanFactory是Spring-IOC的基本实现,而ApplicationContext是BeanFactory的子接口,提供了更多高级特性。ApplicationContext是Spring框架最常用的IOC容器,它除了提供BeanFactory的所有功能外,还提供了更多的企业级特性,例如AOP、事务管理、国际化、事件传播等。 下面是一个简单的Spring-IOC的例子,假设我们有一个UserService接口和一个UserServiceImpl实现类,我们可以通过Spring-IOC容器来创建和管理UserServiceImpl对象: 1.定义UserService接口和UserServiceImpl实现类 ```java public interface UserService { void addUser(User user); } @Service public class UserServiceImpl implements UserService { @Override public void addUser(User user) { // 添加用户的具体实现 } } ``` 2.在Spring配置文件配置UserService实例 ```xml <bean id="userService" class="com.example.service.UserServiceImpl"/> ``` 3.在代码获取UserService实例并使用 ```java ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = context.getBean("userService", UserService.class); User user = new User(); userService.addUser(user); ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值