2.2.1构造器实例化
构造器实例化是指Spring容器通过Bean对应类中默认的无参构造方法来实例化Bean。下面通过一个案例来演示Spring容器是如何通过构造器来实例化Bean的。
- 在Eclipse中,创建一个名为chapter02的Web项目,在该项目的lib目录中加入Spring支持和依赖的JAR包。
2.在chapter02项目的src目录下,创建一个
com.itheima.instance.constructor包,在该包中创建Bean1类。
3.在com.itheima.instance.constructor包中,创建Spring的配置文件beans1.xml, 在配置文件中定义一个id为bean1的Bean,并通过class属性指定其对应的实现类为Bean1。
4.在com.itheima.instance.constructor包中,创建测试类InstanceTest1, 来测试构造器是否能实例化Bean。
5.首先定义了配置文件的路径,然后Sping容器ApplicationContext会加载配置文件。在加载时,Spring容器会通过id为bean1的实现类Bean1中默认的无参构造方法对Bean进行实例化。
6.执行程序后,控制台的输出结果如图所示。
7.从运行结果可以看出,Sping容器已经成功实例化了Bean1.并输出了结果。
2.2.2静态工厂方式实例化
使用静态工厂是实例化Bean的另-种方式。该方式要求开发者创建一个静态工厂的方法来创建Bean的实例,其Bean配置中的class 属性所指定的不再是Bean实例的实现类,而是静态工厂类,同时还需要使用factory-method属性来指定所创建的静态工厂方法。
- 在chapter02 项目的src目录下,创建一个com.itheima.instance.static_factoy包,在该包中创建一个Bean2类,该类与Bean1一样,不需添加任何方法。
- 在com.itheima.instance.static_factoy包中,创建一个MyBean2Factory类,并在类中创建一个静态方法createBean来返回Bean2实例。
3.在com.itheima.instance.static_factoy包中,创建Spring配置文件beans2.xml。
在上述配置文件中,首先通过<bean>元素的id属性定义了一个名称为bean2的Bean,然后由于使用的是静态工厂方法,所以需要通过class 属性指定其对应的工厂实现类为MyBean2Factory。由于这种方式配置Bean后,Spring 容器不知道哪个是所需要的工厂方法,所以增加了factory-method属性来告诉Spring 容器,其方法名称为createBean。
4.在com.itheima.instance.static_factoy包中,创建一个测试类InstanceTest2,来测试使用静态工厂方式是否能实例化Bean。
5.执行程序后,控制台的输出结果如图所示。
从图中可以看到,使用自定义的静态工厂方法,已成功实例化了Bean2。
2.2.3 实例工厂方式实例化
还有一种实例化Bean的方式就是采用实例工厂。此种方式的工厂类中,不再使用静态方法创建Bean实例,而是采用直接创建Bean实例的方式。同时,在配置文件中,需要实例化的Bean也不是通过class属性直接指向的实例化类,而是通过factory-bean属性指向配置的实例工厂,然后使用factory-method属性确定使用工厂中的哪个方法。
- 在chapter02项目的src目录下,创建一个com.itheima.instance.factoy包,在该包中创建Bean3类,该类与Bean1一样,不需添加任何方法。
- 在com.itheima.instance.factoy包中,创建工厂类MyBean3Factory,在类中使用默认无参构造方法输出“bean3工厂实例化中”语句,并使用createBean()方法创建Bean3对象。
3. 在com.itheima.instance.factoy包中,创建Spring配置文件beans3.xml,设置相关后。
在上述配置文件中,首先配置了一个工厂Bean,然后配置了需要实例化的Bean。在id为bean3的Bean中,使用factory-bean属性指向配置的实例工厂,该属性值就是工厂Bean的id。使用factory-method属性来确定使用工厂中的createBean()方法。
4.在com.itheima.instance.factoy的包中,创建测试类InstanceTest3,来测试实例工厂方式能否实例化Bean,编辑后如图所示。
5.执行程序后,控制台的输出结果如图所示。
2.3 Bean的作用域
2.3.2 singleton作用域
singleton是Spring容器默认的作用域,当Bean的作用域为singleton时,Spring 容器说只会存在一个共享的Bean实例,并且所有对Bean的请求,只要id与该Bean的id属性相匹配,就会返回同个Bean实例。singleton作用域对于无会话状态的Bean(如Dao组件、Service组件)来说,是最理想的选择。
在Spring配置文件中,Bean的作用该是通过<bean>元素的scope属性来指定的,该属性值可以设置为singleton、prototype request, session, globalSession、application和websocket七个值,分别表示七种作用域。要将作用城定义成singleton,只需将scope的属性值设置为singleton即可。
在项目chapter02中,创建一个com.itheima.scope包,在包中创建Scope类,该类不需要写任何方法。然后在该包中创建一个配置文件beans4.xml,将上述示例代码写入配置文件中。最后在包中创建测试类ScopeTest来测试singleton作用城。
执行程序后,结果如图:
从图中可以看出,两次输出的结果相同,说明Spring容器只创建了一个Scope类的实例。
2.3.3 prototype作用域
在配置文件中将<bean>元素的scope属性值设置为prototype即可。
再次运行测试类ScopeTest:
从图中可以看出,两次输出的结果不相同,这说明在prototype作用域下,创建了两个不同的Scope类的实例。
2.5 Bean的装配方式
2.5.1 基于XML的装配
- 在项目chapter02的src目录下,创建一个com.itheima.assemble包,在该包中创建User类,并在类中定义usename,password和list集合三个属性及其对应的setter方法。
在该文件中,由于要使用构造注入,所以需要其有参和无参的构造方法。同时,为了输出时能够看到结果,还重写了其属性的toString()方法。
- 在com.itheima.assemble包中,创建配置文件beans5.xml,在配置文件中通过构造注入和设值注入的方式装配User类的实例。
- 在com.itheima.assemble包中,创建测试类XmlBeanAssembleTest,在类中分別获取并输出配置文件中的user1和user2实例。
执行程序后,控制台输出结果:
2.5.2基于Annotation的装配
在Spring中,尽管使用XML配置文件可以实现Bean的装配工作,但如果应用中有很多Bean时,会导致XML配置文件过于臃肿,给后续的维护和升级工作带来-定的困难。 为此,Spring提供了对Annotation (注解)技术的全面支持。
- 在chapter02的src目录下,创建一个com.itheima.annotation包,在该包下创建接口UserDao,并在接口中定义一个save()方法。
- 在com.itheima.annotation包中,创建UserDao接口的实现类UserDaoImpl,实现接口中的save()方法。
- 在com.itheima.annotation包中,创建接口UserService,在接口中同祥定义一个save()方法。
- 在com.itheima.annotation包中,创建UserService接口的实现类UserServiceImpl,该类需要实现接口中的save()方法。
- 在com.itheima.annotation包中,创建控制器类UserController。
- 在com.itheima.annotation包中,创建配置文件beans6.xml,在配置文件中编写基于Annotation装配的代码。
- 在com.itheima.annotation包中,创建测试类AnnotationAssembleTest,在类中编写测试方法并定义配置文件的路径,然后通过Spring容器加载配置文件并获取UserController实例,最后调用实例中的save()方法。
执行程序后,控制台的输出结果如图:
2.5.3自动装配
- 修改2.5.2中的文件UserServiceImpl和文件UserController,分别在文件中添加类属性的setter方法。
- 修改配置文件beans6.xml,将配置文件修改为自动装配形式。
执行程序后,控制台的输出结果如图: