1. Spring概述
1.1. Spring是什么
J2EE三层架构体系
l 表现层(页面数据显示、页面跳转调度)jsp/servlet
l 业务层(业务处理和功能逻辑、事务控制)-serivice
l 持久层(数据存取和封装、和数据库打交道)dao
一站式:
Spring提供了JavaEE各层的解决方案,表现层:Spring MVC,持久层:JdbcTemplate、ORM框架整合,业务层:IoC、AOP、事务控制。
轻量级:Spring的出现取代了EJB的臃肿、低效、繁琐复杂、脱离现实。
1.2. Spring体系架构
1.3. Spring的核心技术
IoC(Inverse of Control 反转控制): 将对象创建权利交给Spring工厂进行管理。
AOP(Aspect Oriented Programming 面向切面编程),基于动态代理功能增强。
1.4. 为什么要学习Spring
2. Spring IOC快速入门
2.1. 什么是IOC
Inverse of Control,控制反转,将对象的创建权力反转给Spring框架!!
解决问题:使用IOC可以解决的程序耦合性高的问题!!
2.2. IOC的原理
2.2.1.准备工作
创建UserDao接口及其实现类UserDaoImpl
package cn.baidu.dao;
public interface UserDao {
public void save();
}
package cn.baidu.dao.impl;
import cn.baidu.dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("持久层:用户保存");
}
}
创建UserService接口及其实现类UserServiceImpl
package cn.baidu.service;
public interface UserService {
public void save();
}
package cn.baidu.service.impl;
import cn.baidu.dao.UserDao;
import cn.baidu.dao.impl.UserDaoImpl;
import cn.baidu.service.UserService;
publicclass UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImpl();
@Override
public void save() {
System.out.println("业务层:用户保存");
userDao.save();
}
}
2.2.2.创建测试类测试
package cn.baidu.test;
import org.junit.Test;
import cn.baidu.service.UserService;
import cn.baidu.service.impl.UserServiceImpl;
publicclass Test1 {
@Test
public void test(){
UserService userService = new UserServiceImpl();
userService.save();
}
}
创建另一个UserDao的实现UserDaoImpl2
package cn.baidu.dao.impl;
import cn.baidu.dao.UserDao;
public class UserDaoImpl2 implements UserDao{
@Override
public void save() {
System.out.println("持久层:用户保存2");
}
}
观察以上程序发现:UserService和UserDao耦合性过高,如果需要换一个UserDao的实现,则需要更改源代码。
2.2.3.创建工厂类解决耦合性的问题
package cn.baidu.utils;
import cn.baidu.dao.UserDao;
import cn.baidu.dao.impl.UserDaoImpl;
public class BeanFactory {
public static UserDao getBean(){
return new UserDaoImpl();
}
}
修改UserServiceImpl实现类获取UserDao的方式
public class UserServiceImpl implements UserService {
// private UserDao userDao = new UserDaoImpl();
// 采用工厂类获取UserDao对象
private UserDao userDao = BeanFactory.getBean();
@Override
public void save() {
System.out.println("业务层:用户保存");
userDao.save();
}
}
观察发现: 当需要更换 UserDao 的实现时,不需要更改 UserServiceImpl 类,但还是要更改工厂类。
2.2.4.创建配置文件彻底解决耦合性的问题
在src下创建配置文件beans.xml
<?xml version="1.0"encoding="UTF-8"?>
<bean id="userDao"class="cn.baidu.dao.impl.UserDaoImpl2"></bean>
修改工厂类,从配置文件读取对象
public class BeanFactory {
//存放所有的对象
private static final Map<String,Object>map = new HashMap<String,Object>();
static{
SAXReader sax = new SAXReader();
try {
Document document = sax.read(BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml"));
Element root = document.getRootElement();
//获取id属性的值
String id = root.attributeValue("id");
//获取class属性的值
String value = root.attributeValue("class");
//根据class属性的值实例化对象
Object obj = Class.forName(value).newInstance();
//把对象存放到Map中
map.put(id, obj);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据id获取对象
* @param id
* @return
*/
public static Object getBean(String id){
return map.get(id);
}
}
修改UserServiceImpl类
public class UserServiceImpl implements UserService {
// private UserDao userDao = new UserDaoImpl();
// 采用工厂类获取UserDao对象
// private UserDao userDao = BeanFactory.getBean();
// 从配置文件中读取需要的对象
private UserDao userDao = (UserDao) BeanFactory.getBean("userDao");
@Override
public void save() {
System.out.println("业务层:用户保存");
userDao.save();
}
}
观察发现:当需要更改UserDao时,只需要更改配置文件就行,不用更改源代码,程序彻底解耦了!!!
2.3. Spring开发包
官网地址:https://spring.io/
下载网址:http://repo.spring.io/libs-release-local/org/springframework/spring/
本次学习采用4.2.4这个版本
开发包目录结构
开发过程中还需要其他开源技术框架依赖Jar包集(dependencies,作用是方便依赖的其他技术的jar的导入):
2.4. Spring IOC入门
2.4.1.新建Java工程spring4_day01,导入jar包
Spring核心容器需要四个jar包
同时还需要与日志相关的两个jar包,从spring-framework-3.0.2.RELEASE-dependencies中寻找
复制log4j.properties到src下:
如何在Java工程中导入jar包?
在Java工程中新建一个目录lib,把需要导入的jar包复制到lib下,右键需要导入的jar包,build path,添加到项目中
2.4.2.创建一个接口和实现类
package cn.baidu.dao;
public interface UserDao {
public void save();
}
package cn.baidu.dao.impl;
import cn.baidu.dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("用户保存...");
}
}
2.3.4.创建Spring的核心配置文件
在src下新建Spring核心配置文件applicationContext.xml
引入约束,配置提示
<?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">
</beans>
2.4.4.配置UserDaoImpl类
<?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 id="userDao"class="cn.baidu.dao.impl.UserDaoImpl"></bean>
</beans>
2.4.5.编写测试类
public class Test1 {
@Test
public void test1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.save();
}
}
测试发现:
我们可以从spring容器中获取对象。
3. Spring中的工厂
3.1. ApplicationContext接口
使用ApplicationContext工厂的接口,使用该接口可以获取到具体的Bean对象
接口下有两个具体的实现类
*ClassPathXmlApplicationContext --加载类路径下的Spring配置文件
*FileSystemXmlApplicationContext --加载本地磁盘下的Spring配置文件
public class Test1 {
@Test
public void test1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.save();
}
@Test
public void test2(){
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("C:/spring/applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.save();
}
}
3.2. BeanFactory工厂
BeanFactory是Spring框架早期的创建Bean对象的工厂接口
/**
* 早期版本的spring工厂:BeanFactory
*/
@Test
public void test3(){
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
System.out.println("工厂对象创建出来了");
UserDao userDao = (UserDao) factory.getBean("userDao");
userDao.save();
}
BeanFactory和ApplicationContext的区别
*BeanFactory --BeanFactory采取延迟加载,第一次getBean时才会初始化Bean
*ApplicationContext -- 在加载applicationContext.xml时候就会创建具体的Bean对象的实例,还提供了一些其他的功能:
* 事件传递
* Bean自动装配
* 各种不同应用层的Context实现
4. Spring配置文件
4.1. id属性
id属性是bean的唯一标识
4.2. class属性
bean的全路径名
<bean id="userDao"class="cn.baidu.dao.impl.UserDaoImpl"/>
4.3. scope属性
scope属性代表Bean的作用范围
singleton:单例(默认值)
prototype:多例,在Spring框架整合Struts2框架的时候,Action类也需要交给Spring做管理,配置把Action类配置成多例!!
request:应用在web应用中,将创建的对象存入到request域中。
session:应用在web应用中,将创建的对象存入到session域中
globalsession:应用在porlet环境下使用。将创建的对象存入到全局的session中。<bean id="userDao"class="cn.baidu.dao.impl.UserDaoImpl"scope="prototype"/>
修改测试类:
@Test
public void test1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("工厂对象创建出来了");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
UserDao userDao1 = (UserDao) applicationContext.getBean("userDao");
userDao.save();
}
测试发现:当scope为prototype时,每次获取bean,都会重新实例化
4.4. init-method属性
当bean被载入到容器的时候调用init-method属性指定的方法
public class UserDaoImpl implements UserDao {
public UserDaoImpl() {
System.out.println("调用了UserDaoImpl的构造方法");
}
public void init(){
System.out.println("调用了init方法...");
}
@Override
public void save() {
System.out.println("用户保存...");
}
}
<bean id="userDao"class="cn.baidu.dao.impl.UserDaoImpl"init-method="init"/>
测试结果:
4.5. destory-method属性
当bean从容器中删除的时候调用destroy-method属性指定的方法
想查看destroy-method的效果,有如下条件:
scope= singleton有效
web容器中会自动调用,但是main函数或测试用例需要手动调用(需要使用ClassPathXmlApplicationContext的close()方法)
@Test
public void test1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("工厂对象创建出来了");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.save();
//要看到destroy方法执行,需要调用ClassPathXmlApplicationContext.close方法
((ClassPathXmlApplicationContext)applicationContext).close();
}
5. Spring生成bean的三种方式
5.1. 无参构造方法
默认调用无参构造方法实例化bean
5.2. 静态工厂实例化方式
通过调用工厂类的静态方法来生成bean
编写DepartmentDao接口
package cn.baidu.dao;
publicinterface DepartmentDao {
public void save();
}
编写DepartmentDaoImpl实现类
package cn.baidu.dao.impl;
import cn.baidu.dao.DepartmentDao;
public class DepartmentDaoImpl implements DepartmentDao{
@Override
public void save() {
System.out.println("部门保存...");
}
}
编写工厂类
package cn.baidu.dao.impl;
import cn.baidu.dao.DepartmentDao;
public class DepartmentDaoFactory {
/**
* 静态工厂方法获取对象
* @return
*/
public static DepartmentDao create(){
return new DepartmentDaoImpl();
}
}
编写applicationContext.xml配置文件
<?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 id="userDao" class="cn.baidu.dao.impl.UserDaoImpl" init-method="init" destroy-method="destory"/>
<bean id="departmentDao" class="cn.baidu.dao.impl.DepartmentDaoFactory" factory-method="create"></bean>
</beans>
5.3. 实例工厂实例化方式
实例工厂代码:
package cn.baidu.dao.impl;
import cn.baidu.dao.DepartmentDao;
public class DepartmentDaoFactory {
/**
* 静态工厂方法获取对象
* @return
*/
public static DepartmentDao create(){
return new DepartmentDaoImpl();
}
/**
* 实例工厂方法获取对象
* @return
*/
public DepartmentDao create1(){
return new DepartmentDaoImpl();
}
}
编写applicationContext.xml
<?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 id="userDao" class="cn.baidu.dao.impl.UserDaoImpl" init-method="init "destroy-method="destory"/>
<!-- <bean id="departmentDao" class="cn.baidu.dao.impl.DepartmentDaoFactory" factory-method="create"></bean> -->
<bean id="departmentDaoFactory" class="cn.baidu.dao.impl.DepartmentDaoFactory"></bean>
<bean id="departmentDao" factory-bean="departmentDaoFactory" factory-method="create1"></bean>
</beans>
6. 依赖注入
6.1. 什么是依赖注入
IOC和DI的概念:
*IOC -- Inverse of Control,控制反转,将对象的创建权反转给Spring!!
*DI -- Dependency Injection,依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件中!!
如果UserServiceImpl的实现类中有一个属性,那么使用Spring框架的IOC功能时,可以通过依赖注入把该属性的值传入进来!!
6.2. 构造方法注入
Car实体类
package cn.baidu.domain;
public class Carimplements Serializable{
privatestaticfinallongserialVersionUID = 1L;
private String name;
private Double price;
public Car(String name, Double price) {
this.name = name;
this.price = price;
}
public String getName() {
returnname;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
returnprice;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return"Car [name=" + name + ", price=" + price + "]";
}
}
配置applicationContext.xml
<?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 id="userDao" class="cn.baidu.dao.impl.UserDaoImpl" init-method="init" destroy-method="destory"/>
<!-- <bean id="departmentDao" class="cn.baidu.dao.impl.DepartmentDaoFactory" factory-method="create"></bean> -->
<bean id="departmentDaoFactory" class="cn.baidu.dao.impl.DepartmentDaoFactory"></bean>
<bean id="departmentDao" factory-bean="departmentDaoFactory" factory-method="create1"></bean>
<!-- 构造方法注入 -->
<bean id="car" class="cn.baidu.domain.Car">
<constructor-arg name="name" value="奥迪A6"></constructor-arg>
<constructor-arg name="price" value="57.3"></constructor-arg>
</bean>
</beans>
运行结果:
6.3. set方法注入
Student实体类
public class Student implements Serializable {
privatestaticfinallongserialVersionUID = 1L;
private Long id;
private String name;
public Long getId() {
returnid;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
returnname;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return"Student [id=" + id + ", name=" + name + "]";
}
}
配置applicationContext.xml
<?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 id="userDao" class="cn.baidu.dao.impl.UserDaoImpl" init-method="init" destroy-method="destory"/>
<!-- <bean id="departmentDao" class="cn.baidu.dao.impl.DepartmentDaoFactory" factory-method="create"></bean> -->
<bean id="departmentDaoFactory" class="cn.baidu.dao.impl.DepartmentDaoFactory"></bean>
<bean id="departmentDao" factory-bean="departmentDaoFactory" factory-method="create1"></bean>
<!-- 构造方法注入 -->
<bean id="car" class="cn.baidu.domain.Car">
<constructor-arg name="name" value="奥迪A6"></constructor-arg>
<constructor-arg name="price" value="57.3"></constructor-arg>
</bean>
<!-- set方法注入 -->
<bean id="student" class="cn.baidu.domain.Student">
<property name="id" value="11"></property>
<property name="name" value="张三"></property>
</bean>
</beans>
测试结果:
注意:采用set方法注入时,类中一定要有无参构造方法,因为spring会先调用无参构造方法实例化对象。
6.4. set方法注入对象
People实体类
public class People implements Serializable {
privatestaticfinallongserialVersionUID = 1L;
private Long id;
private String name;
private Car car;
public Long getId() {
returnid;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
returnname;
}
public void setName(String name) {
this.name = name;
}
public Car getCar() {
returncar;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return"People [id=" + id + ", name=" + name + ", car=" + car + "]";
}
}
配置applicationContext.xml
<!-- set方法注入对象 -->
<bean id="people" class="cn.baidu.domain.People">
<property name="name" value="小明"></property>
<property name="car" ref="car"></property>
</bean>
运行结果:
6.5. set方法其它注入写法
通过set方法注入还有其它两种写法:
6.5.1.p命名空间的写法
新建Car1类
package cn.baidu.domain;
public class Car1 {
private String name;
private double price;
public void setName(String name) {
this.name = name;
}
public void setPrice(doubleprice) {
this.price = price;
}
@Override
public String toString() {
return"Car1 [name=" + name + ", price=" + price + "]";
}
}
在applicationContext.xml中引入p命名空间
采用p:属性名的形式注入值(spring2.5提供的)
<!-- p命名空间注入 -->
<bean id="car1" class="cn.baidu.domain.Car1" p:name="奔驰" p:price="100.2">
</bean>
6.5.2.SpEL的写法(spring3.0提供)
<!-- SpEL注入 -->
<bean id="car1" class="cn.baidu.domain.Car1">
<property name="name" value="#{'哈弗H5'}"></property>
<property name="price" value="#{10}"></property>
</bean>
注入字符串:#{‘字符串’}
注入数字:#{数字}
注入其它对象:#{对象id}
<bean id="people" class="cn.baidu.domain.People">
<property name="name" value="#{'小明'}"></property>
<property name="car" value="#{car}"></property>
</bean>
还可以注入其它对象的属性或方法的返回值
public class CarInfo {
public String getCarName(){
return "宝骏560";
}
public double calculatePrice(){
return Math.random() * 10000;
}
}
<bean id="carInfo"class="cn.baidu.domain.CarInfo"></bean>
<!-- SpEL注入 -->
<bean id="car1" class="cn.baidu.domain.Car1">
<!-- <property name="name" value="#{'哈弗H5'}"></property>
<property name="price" value="#{10}"></property> -->
<property name="name" value="#{carInfo.carName}"></property>
<property name="price" value="#{carInfo.calculatePrice()}"></property>
</bean>
注意:#{carInfo.carName}会调用getCarName方法获取汽车的名称;而#{carInfo.calculatePrice()}会直接调用calculatePrice方法获取汽车价格。
6.6. 数组或list注入
数组和list注入的写法是一样的
新建bean类
public class CollectionBean {
private String[] array;
public void setArray(String[] array) {
this.array = array;
}
@Override
public String toString() {
return"CollectionBean [array=" + Arrays.toString(array) + "]";
}
}
在applicationContext.xml中配置
<bean id="collectionBean" class="cn.baidu.domain.CollectionBean">
<property name="array">
<list>
<value>威少</value>
<value>哈登</value>
<value>莱昂纳德</value>
</list>
</property>
</bean>
6.7. Set集合的注入
public class CollectionBean {
private String[] array;
private Set<String>set;
public void setArray(String[] array) {
this.array = array;
}
public void setSet(Set<String>set) {
this.set = set;
}
@Override
public String toString() {
System.out.println(set.getClass());
return"CollectionBean [array=" + Arrays.toString(array) + ", set=" + set + "]";
}
}
<bean id="collectionBean" class="cn.baidu.domain.CollectionBean">
<property name="array">
<list>
<value>威少</value>
<value>哈登</value>
<value>莱昂纳德</value>
</list>
</property>
<property name="set">
<set>
<value>苹果</value>
<value>梨子</value>
<value>香蕉</value>
</set>
</property>
</bean>
提示:spring在注入set的时,给我们注入的是一个LinkedHashSet,所以在输入set集合中的元素时,是按照我们注入的顺序来的,并不是无序的。
6.8. Map集合的注入
public class CollectionBean {
private String[] array;
private Set<String>set;
private Map<String,String>map;
public void setArray(String[] array) {
this.array = array;
}
public void setSet(Set<String>set) {
this.set = set;
}
public void setMap(Map<String, String>map) {
this.map = map;
}
@Override
public String toString() {
return"CollectionBean [array=" + Arrays.toString(array) + ", set=" + set + ", map=" + map + "]";
}
}
<bean id="collectionBean" class="cn.baidu.domain.CollectionBean">
<property name="array">
<list>
<value>威少</value>
<value>哈登</value>
<value>莱昂纳德</value>
</list>
</property>
<property name="set">
<set>
<value>苹果</value>
<value>梨子</value>
<value>香蕉</value>
</set>
</property>
<property name="map">
<map>
<entrykey="id"value="11"></entry>
<entrykey="name"value="张三"></entry>
<entrykey="age"value="20"></entry>
</map>
</property>
</bean>
Properties的注入
public class CollectionBean {
private String[] array;
private Set<String>set;
private Map<String,String>map;
private Properties props;
public void setArray(String[] array) {
this.array = array;
}
public void setSet(Set<String>set) {
this.set = set;
}
public void setMap(Map<String, String>map) {
this.map = map;
}
public void setProps(Properties props) {
this.props = props;
}
@Override
public String toString() {
return"CollectionBean [array=" + Arrays.toString(array) + ", set=" + set + ", map=" + map + ", props=" + props
+ "]";
}
}
<bean id="collectionBean" class="cn.baidu.domain.CollectionBean">
<property name="array">
<list>
<value>威少</value>
<value>哈登</value>
<value>莱昂纳德</value>
</list>
</property>
<property name="set">
<set>
<value>苹果</value>
<value>梨子</value>
<value>香蕉</value>
</set>
</property>
<property name="map">
<map>
<entry key="id"value="11"></entry>
<entry key="name"value="张三"></entry>
<entry key="age"value="20"></entry>
</map>
</property>
<property name="props">
<props>
<prop key="username">李四</prop>
<prop key="password">123</prop>
</props>
</property>
</bean>
6.9. 配置文件的分离
Spring配置文件的分离有两种方式:
(1)采用import标签导入另一个配置文件
Bean1类Public class Bean1 {
private String xxx;
public String getXxx() {
returnxxx;
}
Public void setXxx(String xxx) {
this.xxx = xxx;
}
@Override
public String toString() {
return "Bean1 [xxx=" + xxx + "]";
}
}
applicationContext2.xml
<?xml version="1.0"encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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 id="bean1" class="cn.itcast.demo.Bean1">
<property name="xxx" value="hello"></property>
</bean>
</beans>
在applicationContext.xml中引入applicationContext2.xml文件
<import resource="applicationContext2.xml"/>
(2)在实例化ApplicationContext的时候,指定多个配置文件
@Test
public void test9(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml");
Bean1 bean1 = (Bean1) ac.getBean("bean1");
System.out.println(bean1);
}