spring作为IOC和AOP的容器框架,可以帮我们管理持久化类的生命周期。以前往往在使用持久化类之前,我们需要自己进行手动实例化,现在有了spring,我们可以将这一操作交给spring来管理。
配置spring
一 引包
引包与配置MVC时的包一样。
二 配置文件
在src目录下建立applicationContext.xml文件,并引入bean注解。添加如下代码:
<!-- 相当于User user = new User() --> <bean class="self.exercise.model.User" id="user"></bean>
这句话就相当于我们自己手动实例化了一个对象。
bean还有一个属性scope当scope值为singleton,只实例化一次对象;当值为propotype,每次都会新创建一个实例。
创建好实例,我们在JUnit测试类中获取这个实例。
@Test public void springTest01() { //读取核心配置文件 ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); //获取实例 User user = ac.getBean("user", User.class); }
创建好实例,如何进行初始化呢?
setter注入方式
这种方式下持久化类中不能生成构造函数。
bean标签的property标签用来初始化参数
<bean class="self.exercise.model.User" id="user" scope="prototype"> <property name="user_id" value="1" /> <property name="account" value="account" /> <property name="user_name"> <value>清雅轩</value> </property> <!--关联对象Role--> <property name="role"> <bean class="self.exercise.model.Role" id="role"> <property name="role_id" value="1" /> <property name="role_name"> <value>管理员</value> </property> </bean> </property> </bean>
初始化参数有两种方式,一种是给value属性赋值;一种使用value标签;还有另一种初始化参数的方式,引入p标签。
当一个对象的变量关联另一个对象,初始化该关联属性时也要为这个类(Role)进行声明代理;当检测到该属性是自定义类,会自动实例化并初始化其中的变量,最后再初始化该关联属性。但是这种声明方式,Role的作用域只在父标签property的范围内,当测试类试图获取Role对象是是获取不到的。
Role role = ac.getBean("role", Role.class); //org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'role' is defined
为解决这个问题,可以在User的bean标签的同级创建Role的bean标签,然后在User bean标签的property中引用Role bean标签。
<!-- 相当于User user = new User() --> <bean class="self.exercise.model.User" id="user" scope="prototype"> <property name="user_id" value="1" /> <property name="account" value="account" /> <property name="user_name"> <value>清雅轩</value> </property> <property name="role"> <ref bean="role"/> </property> </bean> <bean class="self.exercise.model.Role" id="role"> <property name="role_id" value="1" /> <property name="role_name"> <value>管理员</value> </property> </bean>
我们再探讨下p标签初始化参数的方式
首先引入p标签
在bean标签中alt+/提示,会发现p:[类属性名](-ref)的属性,直接赋值或者引用即可。
<!-- 相当于User user = new User() --> <bean class="self.exercise.model.User" id="user" scope="prototype" p:role-ref="role"> <property name="user_id" value="1" /> <property name="account" value="account" /> <property name="user_name"> <value>清雅轩</value> </property> </bean> <bean class="self.exercise.model.Role" id="role" p:role_id="1"> <property name="role_name"> <value>管理员</value> </property> </bean>
构造函数注入方式
在持久化类中生成构造函数
public User(String account, Role role, Integer user_id, String user_name) { this.account = account; this.role = role; this.user_id = user_id; this.user_name = user_name; }
public Role(Integer role_id, String role_name) {this.role_id = role_id; this.role_name = role_name; }
在xml文件中的注入形式
<!-- 相当于User user = new User() --> <bean class="self.exercise.model.User" id="user" scope="prototype"> <!-- index指明了构造方法中第几个参数,顺序可以上下改变 --> <constructor-arg index="0" name="account" type="java.lang.String" value="account"/> <constructor-arg index="2" name="user_id" type="java.lang.Integer" value="1"/> <constructor-arg index="1" name="role" type="self.exercise.model.Role" ref="role"/> <constructor-arg index="3" name="user_name" type="java.lang.String" value="清雅轩"/> </bean> <bean class="self.exercise.model.Role" id="role" > <constructor-arg index="0" name="role_id" type="java.lang.Integer" value="1"/> <constructor-arg index="1" name="role_name" type="java.lang.String" value="超级管理员"/> </bean>
在逻辑清晰的情况下,index和name属性只写其一即可;参数类型也可以忽略。