Spring学习笔记(一):
1.什么是IOC?
IOC:Invert of Control。
即控制反转,把创建对象实例的工作,由程序编写者交给Spring框架。
1.1 传统程序中创建对象
分为两种情况:
-
先创建接口,再创建实现类
public interface UserService{ void sayHello(); } public class UserServiceImp implements UserService { @Override public void sayHello() { System.out.println("Say Hello"); } } public void demo1() { //传统方法 UserService userService = new UserServiceImp(); userService.sayHello(); }
-
先创建接口及其实现类,再定义一个工厂,通过工厂创建对象
public interface UserService{ void sayHello(); } public class UserServiceImp implements UserService { @Override public void sayHello() { System.out.println("Say Hello"); } } public class UserBeanFactory { public UserServiceImp createUserServiceImp(){ return new UserServiceImp(); } } public void demo2(){ UserBeanFactory userBeanFactory = new UserBeanFactory(); UserService us = userBeanFactory.createUserServiceImp(); us.sayHello(); }
1.2 Spring创建对象
Spring可以通过配置文件+反射+工厂的方法,将创建实例的工作,自己完成。
-
首先创建一个applicationContext.xml配置文件,往其中添加bean标签,id的值就是你定义的这个bean的标识,class的值就是你要创建实例的类名的完整路径
<bean id="userService" class="com.ioc.demo1.UserServiceImp"/>
-
定义一个方法,测试是否能真的创建一个实例
public void demo3(){ //在此暂且理解为对配置文件中所有的bean初始化,全部存入一个bean工厂中 ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); //初始化之后,通过1中定义的id值,获取对应的bean //返回是Object类型,需要强转 UserService us = (UserServiceImp) ac.getBean("userService"); us.sayHello(); }
-
此时输出是say hello
2.什么是DI?
DI:Dependency Injection,依赖注入。
就是将一个bean中所对应的类其中的属性通过property标签,注入到bean中,完成对一个实例添加属性的过程。
此过程是通过set方法来实现的。但是因为是基于bean,所以DI是基于IOC的。
public class UserServiceImpl implements UserService {
private String name;
public void setName(String name) {
this.name = name;
}
public void sayHello() {
System.out.println(name);
}
}
<!--此时相当与创建了一个UserServiceImpl的实例,并将其扔入bean缓冲池中-->
<bean id="us" class="com.imooc.ioc.demo1.UserServiceImpl">
<property name="name" value="香蕉"/>
</bean>
3.什么是bean?
默认情况下,在我认为,就是创建一个指定的类的对象实例,bean中的property属性就是类中的属性。
3.1bean的实例化的3种方式
- 默认的类中构造方法实例化(instanceone)
- 静态工厂方法实例化(instancefactory1)
- 实例工厂实例化(instancefactory2)
public class InstanceOne {
public InstanceOne(){
System.out.println("instanceone 实例化");
}
}
public class InstanceFactory1 {
public static InstanceOne createInstanceOne(){
return new InstanceOne();
}
}
public class InstanceFactory2 {
public InstanceOne createInstanceOne(){
return new InstanceOne();
}
}
<!--bean实例化方式1:默认的构造方法实例化-->
<bean id="instance1" class="com.imooc.ioc.demo2.InstanceOne" />
<!--bean实例化方式2:静态工厂实例化-->
<bean id="instancefactory1" class="com.imooc.ioc.demo2.InstanceFactory1" factory-method="createInstanceOne"/>
<!--
bean实例化方式3:实例工厂实例化
先创建工厂bean;
再创建实例的bean,通过instancefactory2指定工厂bean,通过createInstanceOne指定bean对应的一个方法;
-->
<bean id="instancefactory2" class="com.imooc.ioc.demo2.InstanceFactory2" />
<bean id="instance2" factory-bean="instancefactory2" factory-method="createInstanceOne" />
3.2bean的配置
-
id/name属性
- id/name属性对应就是bean的名称
- id的值是唯一的,name的值可以有特殊字符(比如"/")
-
class属性
类的全路径
-
scope属性
Spring创建的bean默认是单例的,那么如果我们想创建多个实例呢?
这就涉及到bean的作用域–scope属性
属性值 说明 singleton Spring默认的,只创建一个实例。 prototype 每调用一次getBean方法都会返回一个新的实例。 request 每次HTTP请求都会创建一个新的bean,此作用域仅限于WebApplicationContext环境。 session 同一个HTTP session共享一个bean,不同的HTTP session使用不同的bean。此作用域仅限于WebApplicationContext环境。
上代码
public class Person {
}
public class ScopeTest {
@Test
public void test1(){
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
Person person1 = (Person) applicationContext.getBean("person");
Person person2 = (Person) applicationContext.getBean("person");
System.out.println(person1);
System.out.println(person2);
}
}
<!--默认情况下,scope=singleton,此时的输出是同一个对象-->
<bean id="person" class="com.imooc.ioc.demo3.Person"/>
<!--此时输出是不同的对象,此时是多例的-->
<bean id="person" class="com.imooc.ioc.demo3.Person" scope="prototype"/>
3.3bean的生命周期
-
init-method:bean在初始化时调用的方法,在类的构造方法之后、destory方法之前运行。
如果是protype的话,会调用多次init-method,并且无法被销毁
-
destory-method:bean在销毁时调用的方法
此方法只在scope = singleton时有效,因为如果是多例的话,Spring无法判断是要销毁哪个bean。
public class Person { public Person(){ System.out.println("Person实例化"); } public void init(){ System.out.println("Person初始化"); } public void destory(){ System.out.println("Person销毁"); } }
public class ScopeTest { @Test public void test1(){ ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Person person = (Person) classPathXmlApplicationContext.getBean("person"); classPathXmlApplicationContext.close();//此时工厂关闭,销毁bean } }
<bean id="person" class="com.imooc.ioc.demo3.Person" init-method="init" destroy-method="destory"/>