Spring的核心内容之一是SpringIOC容器,它负责对象的创建以及处理对象的依赖关系。本文主要复习内容为(1).对象的创建 (2).对象的依赖关系
1).对象的创建
SpringIOC创建对象的方式主要分为以下几种:
- 调用无参数构造器
- 调用带参数构造器
工厂创建对象
工厂类,静态方法创建对象
工厂类,非静态方法创建对象
1.调用无参构造器
<!--默认无参构造器-->
<bean id="user1" class="cn.zj.b_create_obj.User"></bean>
2.调用带参构造器
<!--调用带参数构造器-->
<!--constructor-arg:通过构造函数注入,property:通过setter对应的方法注入。-->
<bean id="user2" class="cn.zj.b_create_obj.User">
<constructor-arg index="0" type="int" value="100"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" value="Jack"></constructor-arg>
</bean>
也可以自己定义一个字符串“javas”然后进行引用
<bean id="str" class="java.lang.String">
<constructor-arg value="Javas"></constructor-arg>
</bean>
<bean id="user3" class="cn.zj.b_create_obj.User">
<constructor-arg index="0" type="int" value="100"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" ref="str"></constructor-arg>
</bean>
3.工厂创建对象
通过工厂类创建对象主要分为两种,一种是通过静态方法创建对象,另一种是通过非静态的方法创建对象。
3.1 通过非静态方法创建对象
通过非静态方法创建对象的步骤一般为:先创建工厂,然后创建user对象,最后调用工厂的实例方法。
<bean id="factory" class="cn.zj.b_create_obj.ObjectFactory"></bean>
<bean id="user4" factory-bean="factory" factory-method="getInstacne"></bean>
其中class:指工厂类型 factory-method:一定是工厂里的“静态方法”
3.2 通过静态方法创建对象
<bean id="user" class="cn.zj.b_create_obj.ObjectFactory" factory-method="getStaticInstance"></bean>
此外Spring的配置文件中,bean节点的还可以使用name属性。id不能有特殊符号,其唯一,且不能以数字开始
name可以有特殊符号。
<bean id="test" name="1test" class="cn.zj.b_create_obj.User"></bean>
相关代码如下:
App.java
package cn.zj.b_create_obj;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
//测试:对象创建
@Test
public void test_IOC()throws Exception{
//创建IOC容器对象
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean1.xml");
//从容器中获取对象
User user = (User) ac.getBean("1test");
System.out.println(user);
}
}
User.java
package cn.zj.b_create_obj;
public class User {
private int id;
private String name;
//Getter,Setter方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//有参构造器
public User(int id, String name) {
System.out.println("--User对象创建【带参数构造器】--");
this.id = id;
this.name = name;
}
//无参构造器
public User() {
super();
System.out.println("--User对象创建【无参数构造器】--");
}
//init_user和destroy_user方法
public void init_user(){
System.out.println("创建对象之后,初始化");
}
public void destroy_user(){
System.out.println("IOC容器销毁,user对象回收");
}
@Override
public String toString() {
return "User[id="+id+",name="+name+"]";
}
}
ObjectFactory.java
package cn.zj.b_create_obj;
//用工厂类来创建对象
public class ObjectFactory {
//实例方法创建对象
public User getInstacne(){
return new User(100,"工厂,调用实例方法");
}
//静态方法创建对象
public static User getStaticInstance(){
return new User(101,"工厂:调用静态方法");
}
}
bean1.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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/spring-context.xsd">
<!-- 对象的创建 -->
<bean id="user1" class="cn.zj.b_create_obj.User"></bean>
<!--1.带参数构造器-->
<!--constructor-arg:通过构造函数注入,property:通过setter对应的方法注入。-->
<bean id="user2" class="cn.zj.b_create_obj.User">
<constructor-arg index="0" type="int" value="100"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" value="Jack"></constructor-arg>
</bean>
<!--定义一个字符串,值是“Jack”,String s=new String("jack");-->
<bean id="str" class="java.lang.String">
<constructor-arg value="Javas"></constructor-arg>
</bean>
<bean id="user3" class="cn.zj.b_create_obj.User">
<constructor-arg index="0" type="int" value="100"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" ref="str"></constructor-arg>
</bean>
<!--3.工厂类创建对象-->
<bean id="factory" class="cn.zj.b_create_obj.ObjectFactory"></bean>
<!--在创建user对象,共factory方法实例方法-->
<bean id="user4" factory-bean="factory" factory-method="getInstacne"></bean>
<!--3.2工厂类:静态方法-->
<bean id="user" class="cn.zj.b_create_obj.ObjectFactory" factory-method="getStaticInstance"></bean>
<bean id="test" name="1test" class="cn.zj.b_create_obj.User"></bean>
</beans>
2).对象的依赖关系
在Spring中,给对象的属性进行赋值是通过DI,依赖注入的方式。主要分为以下几种:
- 通过构造函数
- 通过set方法给属性注入值
- p名称空间
- 自动装配
- 注解
通过构造方法:
<!--通过构造函数 -->
<bean id="user1" class="cn.zj.c_property.User" scope="prototype">
<constructor-arg value="100"></constructor-arg>
<constructor-arg value="Tom"></constructor-arg>
</bean>
通过set方法给属性注入值:
通过set方法给属性注入值,首先必须要提供set方法。通过property,对象中一定有一个setId,setName的方法,用于给属性注入值。
<!--通过set方法给属性注入值 -->
<bean id="user" class="cn.zj.c_property.User" scope="prototype">
<property name="id" value="101"></property>
<property name="name" value="Jack"></property>
</bean>
p名称空间:
传统的方式:
<bean id="user" class="cn.zj.c_property.User" >
<property name="name" value="xxx"></property>
</bean>
给对象属性注入值也可以用p 名称空间,spring3.0以上版本才支持
<bean id="UserDao" class="cn.zj.c_property.UserDao"></bean>
<bean id="UserService" class="cn.zj.c_property.UserService" p:userDao-ref="userDao"></bean>
<bean id="userAction" class="cn.zj.c_property.UserAction" p:userService-ref="userService"></bean>
优化后的P名称空间:
<bean id="user" class="cn.zj.c_property.User" p:name="Jack0001"></bean>
自动装配:
Spring提供自动装配主要是为了简化配置,缺点是不利于后期的维护。根据名称自动装配:autowire="byName",它会自动去IOC容器中找,与属性名同名的引用对象,它会自动装配。
<!-- ###############自动装配############### -->
<bean id="userDao" class="cn.zj.c_property.UserDao"></bean>
<bean id="userService" class="cn.zj.c_property.UserService" autowire="byName"></bean>
<!-- 根据名字自动装配:userAction -->
<bean id="userAction" class="cn.zj.c_property.UserAction" autowire="byName"></bean>
也可以定义到全局,这样就不用每个节点都使用autowire来代替了:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byName">
<!-- ###############自动装配############### -->
<bean id="userDao" class="cn.zj.c_property.UserDao"></bean>
<bean id="userService" class="cn.zj.c_property.UserService></bean>
<!-- 根据名字自动装配:userAction -->
<bean id="userAction" class="cn.zj.c_property.UserAction"></bean>
</beans>
还可以根据类型自动装配:autowire="byType",必须确保该类型在IOC容器中只有一个对象。(代码略)
注解:
采用注解方式可以简化spring的IOC容器的配置,但是有时候不利于维护!
使用注解的步骤一般为:
- 先引入context名称空间:xmlns:context="http://www.springframework.org/schema/context"
- 开启注解扫描:<context:component-scan base-package="cn.itcast.e_anno2"></context:component-scan>
- 使用注解:
@Component 指定把一个对象加入IOC容器
@Repository 作用同@Component; 在持久层使用
@Service 作用同@Component; 在业务逻辑层使用
@Controller 作用同@Component; 在控制层使用
@Resource 属性注入
1) 使用注解,可以简化配置,且可以把对象加入IOC容器,及处理依赖关系(DI)
2) 注解可以和XML配置一起使用。
@Component("userDao") //就相当于bean.xml[<bean id="userDao" class="...">]
<bean id="" class="" >
<property name="userDao" ref="userDao"></property>@Resource相当于这里的配置
</bean?
//Resource(name="userDao") //根据名称查找
private UserDao userDao; //容器中找UserDao类型的变量,找到后就赋值