spring IOC控制反转及IOC实现的三种方式和bean标签使用
IOC: 控制反转,简单的说是指对象的创建不再使用new,而是由spring框架创建。当服务器开始运行时,读取spring的主配置文件,经过spring框架从主配置文件中识别所有的bean标签,然后根据配置,将所有的对象创建出来。创建出来的对象保存在内存空间。
IOC操作可以有三种实现方式:
1、使用默认构造方法创建对象
2、静态工厂创建对象(关键在静态方法)
自定义一个静态的工厂,通过工厂获取对象。
3、实例工厂创建对象
下面演示的是IOC获取对象的三种方式:
项目中SpringTest.java测试类使用junit方式测试即单元测试。lib目录下为测试中需要的spring jar包,log4j.jar为日志包,User.java是测试需要的一个实体类,applicationContext.xml为spring的主配置文件,名称可以任意但官方建议使用该默认名称。MyFactory.java 为演示实例工厂方法创建对象的工厂类,StaticFcatory.java 为演示静态工厂方法创建对象的工厂类。log4j.properties为日志配置文件。本案例使用的spring版本为 spring4.3.9。
创建一个java项目,项目结构如下,:
代码如下:
1、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">
<!--通过框架常用IOC思想实现String对象的创建 -->
<!--bean标签实现对象的创建,IOC方式 -->
<bean id="str" class="java.lang.String"></bean>
<!--创建User对象 -->
<!--方式一:框架使用默认构造方法创建 -->
<bean id="user1" class="cn.sz.pojo.User"></bean>
<!--采用静态工厂的方式创建对象,简单的说就是一个静态的方法 -->
<!-- 方式二:静态工厂方法获取对象 -->
<bean id="c" class="java.util.Calendar" factory-method="getInstance"></bean>
<bean id="user2" class="cn.sz.factory.StaticFactory"
factory-method="getUser"></bean>
<!--方式三:采用实例工厂的方式创建对象 -->
<bean id="factory" class="cn.sz.factory.MyFactory"></bean>
<bean id="user3" class="cn.sz.pojo.User" factory-bean="factory"
scope="prototype"></bean>
</beans>
2、log4j.properties (日志文件)
log4j.rootLogger=DEBUG,console,FILE
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.threshold=INFO
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%5p] - %c -%F(%L) -%m%n
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.maxBackupIndex=100
##log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.FILE.Append=true
log4j.appender.FILE.File=c:/error1.log
log4j.appender.FILE.Threshold=INFO
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%5p] - %c -%F(%L) -%m%n
log4j.appender.FILE.MaxFileSize=1MB
3、SpringTest.java (junit测试类)
package cn.sz.test;
import java.util.Calendar;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.sz.pojo.User;
//测试ioc创建对象
public class SpringTest {
@Test
public void test1() {
// 读取主配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取对象
String str = context.getBean("str", String.class);
System.out.println(str.hashCode());// 打印hash值
}
// 方式一:使用默认构造方法创建对象
@Test
public void test2() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user1 = context.getBean("user1", User.class);
System.out.println(user1.hashCode());// 打印hash值
}
@Test
public void test3() {
// 通过静态方法获取日历对象
Calendar c1 = Calendar.getInstance();
System.out.println(c1);// 打印内存地址
System.out.println("---------------");
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Calendar c2 = ac.getBean("c", Calendar.class);
System.out.println(c2);// 打印内存地址
}
// 方式二:静态工厂方法创建对象
@Test
public void test4() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user2 = ac.getBean("user2", User.class);
System.out.println(user2);// 打印内存地址
}
// 方式三:实例工厂方法创建对象
@Test
public void test5() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user3 = ac.getBean("user3", User.class);
System.out.println(user3);// 打印内存地址
}
}
4、User.java (用户实体类)
package cn.sz.pojo;
public class User {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
5、MyFactory.java (实例工厂方法类)
package cn.sz.factory;
import cn.sz.pojo.User;
public class MyFactory {
// 实例工厂方法获取User对象
public User getUser() {
return new User();
}
}
6、StaticFactory.java (静态工厂方法类)
package cn.sz.factory;
import cn.sz.pojo.User;
public class StaticFactory {
// 静态方法获取User对象
public static User getUser() {
return new User();
}
}
补充内容:
配置文件中的id名称必须唯一,实体类User必须提供无参的构造方法
<bean id="user1" class="cn.sz.pojo.User"></bean>
getBean方法获取对象的第一个参数为在配置文件中对象你要创建的对象的id,第二个参数为该对象的类型对象
User user1 = context.getBean("user1", User.class);
bean标签比较常见的属性:
name: 针对struts中的引用名存在特殊符号的情况时id不能使用则可以使用name,但是现在已经不用.
id: 用于设置对象的引用名称
class: 用于设置类全名路径
scope : singleton(单例),prototype(多例),request,session
singleton设置对象是单例的
prototype设置对象是多例的---在ssh架构针对action类对象常用设置
request设置对象在request范围对象的管理之中
session设置对象在session域对象管理之中