Spring是一个容器,可以帮助我们创建和管理对象。Spring的俩大特性是IOC和AOP。
IOC是指控制反转:IOC是一种思想,IOC把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是 松散耦合,这样也方便测试,利于功能复用,使得程序的整个体系结构变得非常灵活。
示例;
实现控制反转有3种方式(bean的实例化)
- 构造器方式(默认):
示例:
package com.icss.biz;
public class Dog {
private String name;
public Dog(){
System.out.println("初始化Dog");
}
package com.icss.ui;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.icss.biz.Dog;
public class Test {
public static void main(String[] args) {
//IoC容器
ApplicationContext ctx=
new ClassPathXmlApplicationContext("beans.xml");
//从容器中获取对象
Dog dog = (Dog)ctx.getBean("dog");
}
}
<?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">
<bean id="dog" class="com.icss.biz.Dog">
</bean>
</beans>
输出结果:
初始化Dog
注意:当beans配置了有参构造时,有参构造会覆盖无参构造。
示例:
package com.icss.biz;
public class Dog {
private String name;
private int age;
public Dog(){
System.out.println("初始化Dog");
}
public Dog(String name,int age){
this.name = name;
this.age = age;
System.out.println("初始化Dog"+this.name+this.age+"岁了");
}
}
package com.icss.ui;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.icss.biz.Dog;
public class Test {
public static void main(String[] args) {
//IoC容器
ApplicationContext ctx=
new ClassPathXmlApplicationContext("beans.xml");
//从容器中获取对象
Dog dog = (Dog)ctx.getBean("dog");
}
}
<?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">
<bean id="dog" class="com.icss.biz.Dog">
<constructor-arg name="name" value="旺财"></constructor-arg>
<constructor-arg name="age" value="3"></constructor-arg>
</bean>
</beans>
输出结果:
初始化Dog旺财3岁了
注意:以下内容中的name可以换为index=“0”,index="1"即成员变量的序号,结果一样
<constructor-arg name="name" value="旺财"></constructor-arg>
<constructor-arg name="age" value="3"></constructor-arg>
- 静态工厂方式:beans配置工厂类以及工厂类定义创建实例的方法
示例:
package com.icss.biz;
public class Dog {
private String name;
private int age;
public void getname() {
System.out.println("调用工程类生产对象的getname方法");
}
}
package com.icss.biz;
public class StaticFactory {
public static Dog getDog() {
return new Dog();
}
}
package com.icss.ui;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.icss.biz.Dog;
public class Test {
public static void main(String[] args) {
//IoC容器
ApplicationContext ctx=
new ClassPathXmlApplicationContext("beans.xml");
//从容器中获取对象
Dog dog = (Dog)ctx.getBean("dog");
dog.getname();
}
}
<?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">
<bean id="dog" class="com.icss.biz.StaticFactory" factory-method="getDog">
</bean>
</beans>
输出结果:
调用工程类生产对象的getname方法
- 普通工厂方式:初始化工厂类的实例,通过执行工厂类的方法创建对象并返回
package com.icss.biz;
public class Dog {
private String name;
private int age;
public void getname() {
System.out.println("调用工程类生产对象的getname方法");
}
}
package com.icss.biz;
public class Factory {
public Dog createDog() {
return new Dog();
}
}
package com.icss.ui;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.icss.biz.Dog;
import com.icss.biz.Factory;
public class Test {
public static void main(String[] args) {
//IoC容器
ApplicationContext ctx=
new ClassPathXmlApplicationContext("beans.xml");
//从容器中获取对象
Dog dog = (Dog)ctx.getBean("dog");
dog.getname();
}
}
<?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">
<bean id="factory" class="com.icss.biz.Factory">
</bean>
<bean id="dog" factory-bean="factory" factory-method="createDog" >
</bean>
</beans>
输出结果:
调用工程类生产对象的getname方法
beans的xml文件中还可以用以下这种方式引入另外一个xml配置文件
<import resource="引入配置文件相对于当前配置文件的相对路径"/>
那么,现在对象已经有了,我们如何管理这些对象以及这些对象之间的关系呢?------->依赖注入机制
依赖注入有俩种方案
- 手动注入:分为构造注入和Setter注入,
Setter注入示例代码:
package com.icss.biz;
public class Dog {
private String name;
private int age;
public String getName() {
System.out.println("狗狗的名字为"+this.name);
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.icss.biz;
public class Boy {
private String name;
private Dog dog;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
package com.icss.ui;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.icss.biz.Boy;
import com.icss.biz.Dog;
import com.icss.biz.Factory;
public class Test {
public static void main(String[] args) {
//IoC容器
ApplicationContext ctx=
new ClassPathXmlApplicationContext("beans.xml");
//从容器中获取对象
Boy boy = (Boy)ctx.getBean("boy");
System.out.println("男孩的名字为"+boy.getName());
Dog dog = boy.getDog();
dog.getName();
}
}
<?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">
<bean id="dog" class="com.icss.biz.Dog">
<property name="name" value="旺财" ></property>
<property name="age" value="3" ></property>
</bean>
<bean id="boy" class="com.icss.biz.Boy">
<property name="name" value="小王"></property>
<property name="dog" ref="dog" ></property>
</bean>
</beans>
输出结果
男孩的名字为小王
狗狗的名字为旺财
构造注入:Spring在初始化bean组件时调用含参数的构造函数对全局变量进行赋值
示例代码:
package com.icss.biz;
public class Dog {
private String name;
private int age;
public String getName() {
System.out.println("狗狗的名字为"+this.name);
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.icss.biz;
public class Boy {
private String name;
private Dog dog;
public Boy(String name, Dog dog) {
this.name = name;
this.dog = dog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
package com.icss.ui;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.icss.biz.Boy;
import com.icss.biz.Dog;
import com.icss.biz.Factory;
public class Test {
public static void main(String[] args) {
//IoC容器
ApplicationContext ctx=
new ClassPathXmlApplicationContext("beans.xml");
//从容器中获取对象
Boy boy = (Boy)ctx.getBean("boy");
System.out.println("男孩的名字为"+boy.getName());
Dog dog = boy.getDog();
dog.getName();
}
}
<?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">
<bean id="dog" class="com.icss.biz.Dog">
<property name="name" value="旺财" ></property>
<property name="age" value="3" ></property>
</bean>
<bean id="boy" class="com.icss.biz.Boy">
<constructor-arg index="0" value="小明"></constructor-arg>
<constructor-arg index="1" ref="dog"></constructor-arg>
</bean>
</beans>
运行结果:
男孩的名字为小明
狗狗的名字为旺财
- 自动注入(了解即可)
bean的初始化时间:(Spring创建javaBean的时间)
- 当scope=“prototype”,每次在获取对象的实例时创建一个对象的实例。
- 当scope=“singleton”,会根据bean标签的lazy-init属性值选择创建的时间:(默认default相当于flase)
当lazy-init=“true”, 第一次获取对象实例时创建对象
当lazy-init=“false",在容器加载时创建对象。
bean的销毁:
Spring在创建bean实例后,调用bean的初始化方法,Spring容器关闭后,bean不在被Spring容器调用,进入垃圾可回收阶段,在容器关闭之前,会调用bean的销毁方法(只有scope="singleton"时,bean才会执行销毁方法)