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属性只写其一即可;参数类型也可以忽略。