IOC思想 Inversion of Control 反转控制
- 反转资源获取的方向
- 通过Spring来创建对象 管理对象
XML方式来配置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" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
xmlns:p="http://www.springframework.org/schema/p">
<!--
配置Bean
class:bean的全类名,通过反射的方式在IOC 容器中创建bean,要求容器中必须有无参数的构造器
id:标识容器中的bean id唯一
-->
<bean id="student" class="com.datou.model.Student">
<!--通过setter方法进行注入-->
<property name="name" value="Tom"></property>
<property name="age" value="18"></property>
</bean>
<bean id="student1" class="com.datou.model.Student">
<property name="name" value="Tom"></property>
<property name="age" value="18"></property>
</bean>
<bean id="teacher" class="com.datou.model.Teacher">
<!--通过构造方法来配置bean的属性-->
<!--如果字面值包含特殊字符可以使用<![CDATA[]]包裹起来-->
<!--属性值也可以使用value子节点进行配置-->
<constructor-arg index="0">
<value><![CDATA[<jack>]]></value>
</constructor-arg>
<constructor-arg value="30" index="1"></constructor-arg>
</bean>
<!--使用构造器注入属性值可以指定参数的位置和类型以区分重载构造器-->
<bean id="teacher2" class="com.datou.model.Teacher">
<constructor-arg value="24" type="int"></constructor-arg>
<!--<constructor-arg type="int">-->
<!--<value>24</value>-->
<!--</constructor-arg>-->
</bean>
<bean id="person" class="com.datou.model.Person">
<property name="naem" value="DaRen"></property>
<property name="age" value="25"></property>
<!--可以使用property的ref属性建立bean之间的引用关系-->
<property name="student" ref="student"></property>
<!--<property name="teacher" ref="teacher"></property>-->
<!--也可以使用ref标签-->
<!--<property name="teacher">-->
<!--<ref bean="teacher"></ref>-->
<!--</property>-->
<!--也可以使用内部bean 不能被外部引用只能在内部使用-->
<property name="teacher">
<bean class="com.datou.model.Teacher">
<constructor-arg name="name" value="Yali"></constructor-arg>
<constructor-arg name="age" value="26"></constructor-arg>
</bean>
</property>
</bean>
<bean id="person1" class="com.datou.model.Person">
<constructor-arg value="XiaoRen"></constructor-arg>
<constructor-arg value="20"></constructor-arg>
<constructor-arg ref="teacher"></constructor-arg>
<!--<constructor-arg ref="student"></constructor-arg>-->
<!--赋值-null-->
<!--<constructor-arg><null></null></constructor-arg>-->
<constructor-arg ref="student"></constructor-arg>
<!--为级联属性赋值 注意:属性需要先初始化后才可以为级联属性赋值,否则会有异常,和Struts2不同-->
<property name="student.name" value="test"></property>
</bean>
<!--测试如何配置集合属性-->
<bean id="perlist" class="com.datou.model.PerLIst">
<property name="name" value="PL"></property>
<property name="age" value="19"></property>
<property name="students">
<!--使用list节点为list类型的属性赋值-->
<list>
<ref bean="student"></ref>
<ref bean="student1"></ref>
<!--同样可以使用内部bean-->
<bean class="com.datou.model.Student">
<constructor-arg name="name" value="Yali"></constructor-arg>
<constructor-arg name="age" value="26"></constructor-arg>
</bean>
</list>
</property>
</bean>
<!--配置Map的属性值-->
<bean id="pmap" class="com.datou.model.PerMap">
<property name="name" value="PM"></property>
<property name="age" value="22"></property>
<property name="students">
<!--通过map节点及map的 entry子节点配置map的成员变量-->
<map>
<entry key="a" value-ref="student"></entry>
<entry key="b" value-ref="student1"></entry>
</map>
</property>
</bean>
<!--配置properties 属性值-->
<bean id="dateSources" class="com.datou.model.DateSources">
<property name="properties">
<!--使用props 和prop子节点来为Properties属性赋值-->
<props>
<prop key="user">root</prop>
<prop key="password">admin</prop>
<prop key="jdbcUrl">jdbc://mysql</prop>
<prop key="driverClass">com.mysql.jdbc.java</prop>
</props>
</property>
</bean>
<!--配置独立的集合bean,以供多个bean进行使用 需要导入util的命名空间-->
<util:list id="students">
<ref bean="student"></ref>
<ref bean="student1"></ref>
</util:list>
<bean id="perlist1" class="com.datou.model.PerLIst">
<property name="name" value="pll"></property>
<property name="age" value="88"></property>
<property name="students">
<ref bean="students"></ref>
</property>
</bean>
<!--通过p的命名空间为bean的属性赋值,先需要导入p的命名空间-->
<bean id="person2" class="com.datou.model.Person" p:naem="ppl" p:age="77" p:student-ref="student"
p:teacher-ref="teacher2"></bean>
<!--可以使用autowire属性指定装配的方式
byName 根据bean的名字和当前bean的setter属性风格进行自动装配,若有匹配的则进行匹配,如没有匹配的则不装配
byType 根据bean的类型,和当前bean的属性的类型进行自动装配,如果IOC 容器中有一个以上的的类型匹配的bean,则抛异常
-->
<!--缺点,不够灵活,不够清晰-->
<bean id="autoPerson" class="com.datou.model.AutoPerson"
p:name="au" p:age="21" autowire="byName"></bean>
<!--配置继承-->
<bean id="jiChen" class="com.datou.model.JiChen" p:name="ji" p:age="21"></bean>
<!--抽象bean bean的abstract 为True 不能被IOC 容器初始化,只用来被继承 做为模板使用 可以忽略掉class
若某一个bean的class属性没有指定则该bean一定是一个抽象bean-->
<bean id="jiChen1" p:name="ji1" p:age="21" abstract="true"></bean>
<!--此时两个bean的配置有重复信息,我们可以使用继承,来减少配置-->
<!--bean的配置继承:使用bean的parent的属性 指定继承那个bean的配置-->
<bean id="jiChen2" class="com.datou.model.JiChen" p:name="ji2" parent="jiChen1"></bean>
<bean id="jiChen3" class="com.datou.model.JiChen" p:name="ji1" p:age="21"></bean>
<!--bean的依赖关联-->
<!-- depends-on 要求配置bean的时候必须有一个关联,也就是authop这个bean依赖于student8 必须有这个依赖才能IOC
容器才能初始化authop这个bean-->
<bean id="student8" class="com.datou.model.Student" p:name="ss" p:age="12"></bean>
<bean id="authop" class="com.datou.model.AutoPerson" p:name="aa" p:age="33" depends-on="student8"></bean>
<!--bean的作用域-->
<!--使用bean的scope来创建bean的作用域
singleton: 默认值 容器初始化时创建bean的实例,在整个容器的声明周期内只创建一个bean 单列的
prototype: 原型的 容器初始化时候不创建bean的实例,而是才每次请求时候创建一个bean的新实例并返回-->
<bean id="student9" class="com.datou.model.Student" p:name="jijsf" p:age="13" scope="prototype"></bean>
</beans>
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">
<!-- 引入外部属性文件-->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:db.propertidbes"
p:fileEncoding="utf-8"/>
<bean id="dataSource" class="com.datou.model.DateSources">
<property name="properties">
<props>
<prop key="user">${user}</prop>
<prop key="password">${password}</prop>
<prop key="jdbcUrl">${jdbcUrl}</prop>
<prop key="driverClass">${driverClass}</prop>
</props>
</property>
</bean>
<!--使用spring的spel表达式类似于EL-->
<bean id="student" class="com.datou.model.Student">
<!--使用spel为属性赋值一个字面值 基本数据类型和string类型-->
<property name="name" value="#{'ui'}"></property>
<property name="age" value="66"></property>
</bean>
<bean id="student1" class="com.datou.model.Student">
<property name="name" value="#{'ui'}"></property>
<property name="age" value="66"></property>
<!--使用spel引用类的静态属性-->
<property name="ts" value="#{T(java.lang.Math).PI*80}"></property>
</bean>
<bean id="teacher" class="com.datou.model.Teacher" p:name="tes" p:age="43"></bean>
<bean id="pe" class="com.datou.model.Person">
<property name="naem" value="#{'ui'}"></property>
<!--使用spel引用其他bean的属性-->
<property name="age" value="#{student.age}"></property>
<!--使用spel引用其他bean的属性-->
<property name="student" value="#{student}"></property>
<property name="teacher" value="#{teacher}"></property>
<!--使用spel中的运算符-->
<property name="test" value="#{teacher.age>33?66:45}"></property>
</bean>
<!--Spring IOC 容器bean的生命周期-->
<bean id="student2" class="com.datou.model.Student" init-method="ini" destroy-method="destory">
<property name="name" value="afaf"></property>
</bean>
<!--配置bean的后置处理器-->
<!--实现BeanPostProcessor 接口 具体提供两个方法
postProcessBeforeInitialization(Object bean, String beanName) init-method之前被调用
postProcessAfterInitialization(Object bean, String beanName) init-method之后被调用
参数
bean:bean实例本身
beanName IOC容器配置的bean的名字
返回值:实际返回给用户那个bean 可以修改方法中bean的返回 ,甚至返回一个新的bean-->
<!--<bean class="com.datou.model.MyBeanPostProcess"></bean>-->
<!--通过静态工厂方法来获取bean对应的实例-->
<!--class:执向静态工厂方法的全类名-->
<!--factory-method 指定静态工厂方法名字-->
<!--constructor-arg: 如果工厂方法需要传入才参数则需要用constructor-arg 配置参数-->
<bean id="ss" class="com.datou.model.StaticFactory" factory-method="getStudent">
<constructor-arg value="s1"></constructor-arg>
</bean>
<!--实例工厂方法 和静态工厂方法类似不过要先配置工厂的实例
factory-bean: 对应实例工厂实例
然后其他参数和静态工厂方法一样-->
</beans>
对应的类文件
package com.datou.model;
public class AutoPerson {
private String name;
private int age;
private Student student;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
@Override
public String toString() {
return "AutoPerson{" +
"name='" + name + '\'' +
", age=" + age +
", student=" + student +
'}';
}
}
package com.datou.model;
import java.util.Properties;
public class DateSources {
private Properties properties;
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
return "DateSources{" +
"properties=" + properties +
'}';
}
}
package com.datou.model;
public class JiChen {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "JiChen{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.datou.model;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcess implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization" + bean + "," + beanName);
if ("car".equals(bean)) {
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization" + bean + "," + beanName);
Student s = new Student();
s.setName("112124312");
return s;
}
}
package com.datou.model;
import java.util.List;
public class PerLIst {
private String name;
private int age;
private List<Student> students;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "PerLIst{" +
"name='" + name + '\'' +
", age=" + age +
", students=" + students +
'}';
}
}
package com.datou.model;
import java.util.Map;
public class PerMap {
private String name;
private int age;
private Map<String, Student> students;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Map<String, Student> getStudents() {
return students;
}
public void setStudents(Map<String, Student> students) {
this.students = students;
}
@Override
public String toString() {
return "PerMap{" +
"name='" + name + '\'' +
", age=" + age +
", students=" + students +
'}';
}
}
package com.datou.model;
public class Person {
private String naem;
private int age;
private Teacher teacher;
private Student student;
private int test;
public int getTest() {
return test;
}
public void setTest(int test) {
this.test = test;
}
public String getNaem() {
return naem;
}
public void setNaem(String naem) {
this.naem = naem;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
@Override
public String toString() {
return "Person{" +
"naem='" + naem + '\'' +
", age=" + age +
", teacher=" + teacher +
", student=" + student +
", test=" + test +
'}';
}
public Person(String naem, int age, Teacher teacher, Student student) {
this.naem = naem;
this.age = age;
this.teacher = teacher;
this.student = student;
}
public Person() {
}
}
package com.datou.model;
import java.util.HashMap;
import java.util.Map;
public class StaticFactory {
private static Map<String, Student> map = new HashMap<String, Student>();
static {
map.put("s1", new Student("x", 12));
map.put("s2", new Student("x2", 121));
}
public static Student getStudent(String name) {
Student s = map.get(name);
return s;
}
}
package com.datou.model;
public class Student {
private String name;
private int age;
private double ts;
public double getTs() {
return ts;
}
public void setTs(double ts) {
this.ts = ts;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
System.out.println("setName" + name);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", ts=" + ts +
'}';
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
System.out.println("Student is Constructor.....");
}
public void ini(){
System.out.println("init......");
}
public void destory(){
System.out.println("destory......");
}
}
package com.datou.model;
public class Teacher {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
public Teacher(int age) {
this.age = age;
}
public Teacher() {
}
}
对应的main函数
package com.datou.test;
import com.datou.model.*;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
// 1.创建Spring的IOC容器 会调用当构造方法,进行对象创建,调用setXxx进行赋值
//ApplicationContext 代表IOC容器
//ClassPathXmlApplicationContext 是ApplicationContext接口的实现类,该类实现从类路径加载配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
// 2.从IOC 容器对象中获取bean的实例
//利用id定位到IOC容器中的bean 需要强制类型转换
//Student tom = (Student) ctx.getBean("student");
//利用类型返回IOC容器中的bean,但要求IOC容器中必须只有一个该类型的bean,不需要强制类型转换
// 下面是错误配置实例
/*
* <bean id="student" class="com.datou.model.Student">
<property name="name" value="Tom"></property>
<property name="age" value="18"></property>
</bean>
<bean id="student2" class="com.datou.model.Student">
<property name="name" value="Tom"></property>
<property name="age" value="18"></property>
</bean>
Student tom = (Student) ctx.getBean(Student.class);
* */
Student tom = (Student) ctx.getBean("student");
// 3. 调用实例对应方法
//System.out.println(tom);
Teacher jack = (Teacher) ctx.getBean("teacher");
Teacher luc = (Teacher) ctx.getBean("teacher2");
Person daTou = (Person) ctx.getBean("person");
Person daTou8 = (Person) ctx.getBean("person2");
Person daTou1 = (Person) ctx.getBean("person1");
PerLIst daTou2 = (PerLIst) ctx.getBean("perlist");
PerLIst daTou6 = (PerLIst) ctx.getBean("perlist1");
PerMap daTou3 = (PerMap) ctx.getBean("pmap");
DateSources daTou4 = ctx.getBean(DateSources.class);
JiChen j=(JiChen) ctx.getBean("jiChen");
JiChen j1=(JiChen) ctx.getBean("jiChen2");
JiChen j2=(JiChen) ctx.getBean("jiChen3");
AutoPerson s=(AutoPerson) ctx.getBean("autoPerson");
AutoPerson aa=(AutoPerson) ctx.getBean("authop");
System.out.println(jack);
System.out.println(luc);
System.out.println(daTou);
System.out.println(daTou1);
System.out.println(daTou2);
System.out.println(daTou3);
System.out.println(daTou4);
System.out.println(daTou6);
System.out.println(daTou8);
System.out.println(s);
System.out.println(j);
System.out.println(j1);
System.out.println(j2);
System.out.println(aa);
Student ast=(Student) ctx.getBean("student9");
Student ast1=(Student) ctx.getBean("student9");
System.out.println(ast==ast1);
}
}
package com.datou.test;
import com.datou.model.DateSources;
import com.datou.model.Person;
import com.datou.model.Student;
import com.datou.model.Teacher;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main1 {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("dateSource-spring.xml");
DateSources s = (DateSources)ctx.getBean("dataSource");
System.out.println(s);
Student st=(Student)ctx.getBean("student");
Student st1=(Student)ctx.getBean("student1");
Person t=(Person)ctx.getBean("pe") ;
System.out.println(st);
System.out.println(st1);
System.out.println(t);
Student st2=(Student)ctx.getBean("student2");
System.out.println(st2);
Student ss=(Student)ctx.getBean("ss") ;
System.out.println(ss);
((ClassPathXmlApplicationContext) ctx).close();
}
}
对应的属性文件
user=root
password=admin
driverClass=com.mysql.Jdbc.Driver
jdbcUrl=jdbc:mysql//test
对应的项目目录结构
.
├── lib
│ ├── aopalliance-1.0.jar
│ ├── commons-logging-1.2.jar
│ ├── spring-aop-4.3.18.RELEASE.jar
│ ├── spring-aspects-4.3.18.RELEASE.jar
│ ├── spring-beans-4.3.18.RELEASE.jar
│ ├── spring-context-4.3.18.RELEASE.jar
│ ├── spring-context-support-4.3.18.RELEASE.jar
│ ├── spring-core-4.3.18.RELEASE.jar
│ ├── spring-expression-4.3.18.RELEASE.jar
│ ├── spring-instrument-4.3.18.RELEASE.jar
│ ├── spring-instrument-tomcat-4.3.18.RELEASE.jar
│ ├── spring-jdbc-4.3.18.RELEASE.jar
│ ├── spring-jms-4.3.18.RELEASE.jar
│ ├── spring-messaging-4.3.18.RELEASE.jar
│ ├── spring-orm-4.3.18.RELEASE.jar
│ ├── spring-oxm-4.3.18.RELEASE.jar
│ ├── spring-test-4.3.18.RELEASE.jar
│ └── spring-tx-4.3.18.RELEASE.jar
├── out
│ └── production
│ └── testSpringWeb
│ ├── com
│ │ └── datou
│ │ ├── model
│ │ │ ├── AutoPerson.class
│ │ │ ├── DateSources.class
│ │ │ ├── JiChen.class
│ │ │ ├── MyBeanPostProcess.class
│ │ │ ├── PerLIst.class
│ │ │ ├── PerMap.class
│ │ │ ├── Person.class
│ │ │ ├── StaticFactory.class
│ │ │ ├── Student.class
│ │ │ └── Teacher.class
│ │ └── test
│ │ ├── Main.class
│ │ └── Main1.class
│ ├── dateSource-spring.xml
│ ├── db.propertidbes
│ └── spring-config.xml
├── src
│ ├── com
│ │ └── datou
│ │ ├── model
│ │ │ ├── AutoPerson.java
│ │ │ ├── DateSources.java
│ │ │ ├── JiChen.java
│ │ │ ├── MyBeanPostProcess.java
│ │ │ ├── PerLIst.java
│ │ │ ├── PerMap.java
│ │ │ ├── Person.java
│ │ │ ├── StaticFactory.java
│ └── spring-config.xml
└── testSpringWeb.iml