一、Spring配置文件
1、Bean标签基本配置
用于配置对象交由Spring来创建
默认情况下它调用的是类中的无参构造函数,如果没有则不能创建成功
基本属性:
- id:Bean实例在Spring容器中的唯一标识
- class:Bean的全限定名称
2、Bean标签范围配置
scope指的是对象的作用范围
1)当scope的取值为singleton时:
Bean的实例化个数:1个
Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例
- 对象创建:当应用加载,创建容器时,对象就被创建了
- 对象运行:只要容器在,对象一直活着
- 对象销毁:当应用卸载,销毁容器时,对象就被销毁了
2)当scope的取值为prototype时:
Bean的实例化个数:多个
Bean的实例化时机:当调用getBean()方法时实例化Bean
Bean的生命周期:
- 对象创建:当使用对象时(getBean),创建新的对象实例
- 对象运行:只要对象在使用中,就一直活着
- 对象销毁:当对象长时间不用时,就会被Java的垃圾回收站回收
3、Bean的生命周期配置
- init-method:指定类中的初始化方法名称
- destroy-method:指定类中销毁方法名称
执行顺序:创建对象->执行初始化方法->容器关闭/对象不用时执行销毁方法
4、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 id="userDao" class="cn.ken.dao.impl.UserDaoImpl" scope="singleton" init-method="init" destroy-method="destroy"></bean> <!-- 静态工厂方法 --> <bean id="userDao" class="cn.ken.factory.StaticFactory" factory-method="getuserDao"></bean> <!-- 实例工厂方法 --> <bean id="factory" class="cn.ken.factory.DynamicFactory"></bean> <bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean> </beans>
静态工厂——因为是静态方法,所以不需要创建静态工厂的对象就可以直接通过factory-method调用他的构造方法
public class StaticFactory { public static UserDao getuserDao(){ return new UserDaoImpl(); } }
动态工厂——需要先实例化动态工厂的对象(即需要配置一个该工厂的bean),才能通过这个对象调用factory-method方法来创建userDao对象
public class DynamicFactory { public UserDao getUserDao(){ return new UserDaoImpl(); } }
因为有一些对象的创建不是通过无参构造函数创建,比如JDBC中Connection对象是用DriverManager.getConnection方法获取的,这时候就需要通过后面两种方法创建
5、Bean的依赖注入
实际开发中,我们需要在Spring容器中配置UserService和UserDao两个bean,当在界面层中获取UserService实例时,UserService实例内部需要Userdao实例,按照以往的做法,我们需要在Spring容器外部获取两次beanerService实例内部需要Userdao实例,按照以往的做法,我们需要在Spring容器外部获取两次bean,如下:
public class UserController { public static void main(String[] args) { ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) app.getBean("userService"); userService.save(); } }
public class UserServiceImpl implements UserService { @Override public void save() { ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao) app.getBean("userDao"); userDao.save(); } }
相当于是在Spring容器外将Dao组装到Service内部完成的操作
然而因为UserService和UserDao都在Spring容器中,而最终程序使用的是UserService,所以我们可以直接在Spring容器中把UserDao设置到UserService内部,如下:
<bean id="userDao" class="cn.ken.dao.impl.UserDaoImpl"></bean> <bean id="userService" class="cn.ken.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"></property> </bean>
property中name对应的是UserServiceImpl中的set方法的名字(即属性名),ref表示通过哪个bean创建对象传给这个方法的参数
这样的话就只需要在界面层获取一次Service的Bean就行了,Service层中的getBean方法不再需要,因为其在容器内部已经装配了UserDao,如下:
public class UserServiceImpl implements UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void save() { // ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); // UserDao userDao = (UserDao) app.getBean("userDao"); // userDao.save(); userDao.save(); } }
当然如果在业务层不是通过getBean获取的UserService而是通过new获取,则执行save方法会出现空指针异常,因为UserService中的UserDao属性并没有赋初值,只有通过bean获取的才会装配有UserDao对象
6、依赖注入的概念
依赖注入:它是Spring框架核心IOC的具体实现
在编写程序时,通过控制反转,把对象的创建交给了Spring,但是代码中不可能出现没有依赖的情况,IOC解耦只是降低了他们的依赖关系,但不会消除。例如业务层仍然会调用持久层的方法
那这种业务层和持久层的依赖关系,在使用Spring之后,就让Spring来维护了,简单地说就是坐等框架把持久层对象传入业务层,而不用我们自己去获取
注入方式
1)set方法注入
上文所演示的方法即为set方法注入,该方法可以有简便的写法:P命名空间注入
P命名空间注入本质也是set方法注入,但是写法更为简便,首先引入p命名空间:xmln:p="http://www.springframework.org/schema/p",
其次修改注入方式:
2)有参构造函数注入
<bean id="userDao" class="cn.ken.dao.impl.UserDaoImpl"></bean> <bean id="userService" class="cn.ken.service.impl.UserServiceImpl"> <constructor-arg name="userDao" ref="userDao"></constructor-arg> </bean>
其中name表示的是有参构造函数的参数名,ref表示通过哪个bean创建对象传给这个参数
//需要现在UserServiceImpl中添加有参构造函数 private UserDao userDao; public UserServiceImpl() { } public UserServiceImpl(UserDao userDao) { this.userDao = userDao; }
7、Bean的依赖注入的数据类型
上面的操作,都是注入的引用Bean,除了对象的引用可以注入,普通数据类型,集合等都可以在容器中进行注入
以下演示set方法注入(默认类中已经有了对应的setter方法):
1)普通数据类型
<bean id="userService" class="cn.ken.service.impl.UserServiceImpl"> <property name="name" value="cyh"></property> <property name="age" value="19"></property> </bean>
此处注入的是普通数据类型,故property中使用的是value属性而不是ref属性,ref属性是用于注入对象的引用
2)集合
public class UserServiceImpl implements UserService { private List<String> strList; private Map<String, User> userMap; private Properties properties; public void setStrList(List<String> strList) { this.strList = strList; } public void setUserMap(Map<String, User> userMap) { this.userMap = userMap; } public void setProperties(Properties properties) { this.properties = properties; } @Override public void save() { System.out.println(strList); System.out.println(userMap); System.out.println(properties); } }
<bean id="userService" class="cn.ken.service.impl.UserServiceImpl"> <property name="strList"> <list> <value>aaa</value> <value>bbb</value> <value>ccc</value> </list> </property> <property name="userMap"> <map> <entry key="map1" value-ref="user1"></entry> <entry key="map2" value-ref="user2"></entry> </map> </property> <property name="properties"> <props> <prop key="prop1">ppp1</prop> <prop key="prop2">ppp2</prop> <prop key="prop3">ppp3</prop> </props> </property> </bean> <bean id="user1" class="cn.ken.domain.User"> <property name="name" value="cyh"></property> <property name="addr" value="st"></property> </bean> <bean id="user2" class="cn.ken.domain.User"> <property name="name" value="czk"></property> <property name="addr" value="gd"></property> </bean>
输出结果
[aaa, bbb, ccc] {map1=User{name='cyh', addr='st'}, map2=User{name='czk', addr='gd'}} {prop2=ppp2, prop1=ppp1, prop3=ppp3}
8、引入其他配置文件(分模块开发)
实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以可以将部分配置拆解到其他配置文件中,而在Spring主配置文件中通过import标签加载
9、总结
<bean>标签 id属性:在容器中Bean实例的唯一标识,不允许重复 class属性:要实例化的Bean的全限定名 scope属性:Bean的作用范围,常用是singleton(默认)和prototype <property>标签:属性引入 name属性:属性名称 value属性:注入的普通属性值 ref属性:注入的对象引用值 <list>标签 <map>标签 <propos>标签 <constructor-arg>标签 //内置属性与标签同property <import>标签:导入其他的Spring的分文件