学习Spring的容器功能,就是创建管理对象的能力
使用Spring
-
添加依赖——使用IDEA开发工具建立maven项目
1 <dependency> 2 <groupId>org.springframework</groupId> 3 <artifactId>spring-context</artifactId> 4 <version>5.0.2.RELEASE</version> 5 </dependency>
-
创建XML文件:使用XML文件配置Bean
使用XML文件配置元数据,让Spring能够管理Bean的实例和依赖关系。
要通过XML在Spring IOC容器里声明Bean,首先需要创建XML Bean配置文件,我们在项目的源代码src目录想创建一个名叫beans.xml的配置文件,然后写出一个基于XML配置的基本结构。
-
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 5 <!--配置Bean--> 6 </beans>
在使用基于XML的方式配置元数据的时候,XML有一个根元素就是beans,我们需要在<beans>元素中添加一个或者多个<bean>元素,<bean>元素的配置根据需要和应用程序中实际使用的对象一一对应。
-
配置bean
1 <!--方法一:值接class配置,实例化的是class代表的对象--> 2 <!--别名使用空格,分号,逗号均可以,还可以混合使用--> 3 <bean id="stu" name="ss student,stus" class="com.Student"/> 4 5 <!--方法二:工厂方法--> 6 <!--静态--> 7 <bean id="stuFactory" class="com.StudentFactory" factory-method="getStudent"/> 8 <!--非静态--> 9 <bean id="tea" class="com.StudentFactory"/> 10 <bean id="teaFactory" class="com.StudentFactory" factory-bean="tea" factory-method="getTeacher"/> 11 12 <!--方法三:FactoryBean--> 13 <bean id="factoryBean" class="com.StudentFactoryBean"/>
事实上,关于bean配置还有很多其他的属性,如下图,<bean>常见的属性。
属性名 | 可能值 | 默认值 | 作用 |
id | Bean的唯一标识名。它必须是合法的XML ID,在整个XML文档中唯一 | ||
name |
用来为id创建一个或者多个别名,它可以是任意的字母符号,可以指定多个别名,多个别名之间用逗号或者空格分开 |
||
class | 用来定义类的权限定名 | ||
parent |
Bean可以定义它所引用它的父类Bean的配置,指定了parent后Bean会继承parent都所有配置, 子类Bean也可以覆盖父类Bean的配置,采用这种方式可以达到配置重用的目的 |
||
abstract |
true false |
false | 用来Bean是否为抽象Bean。它表示这个Bean将不会被实例化,一般用于父类Bena,因为父类Bean主要是供子类Bean继承使用 |
singleton |
true false |
true |
定义Bean是否是singleton(单例配置模式),如果设为“true”,则在BeanFactory 作用范围内,只维护此Bean 的一个实例。 如果设为“flase”,Bean 将是Prototype (原型) 状态,BeanFactory 将为每次Bean 请求创建一个新的Bean 实例。 |
lazy-init |
true false default |
default |
用来定义这个Bean 是否实现懒初始化。如果为“true”,它将在BeanFactory 启动时初始化所有的Singleton Bean.反之, 如果为“false”,它只在Bean 请求时才开始创建Singleton Bean。 |
autowire |
no byName byType constructor autodetect |
no |
no: 不使用自动装配功能。 byName:通过Bean 的属性名实现自动装配。 byType:通过Bean 的类型实现自动装配。 const ructor: 类似于byType,但它是用于构造函数的参数的自动组装。 autodetect" :通过Bean 类的反省机制(introspection)决定是使用“constructor”还是使用“byType” |
depends-on | 这个Bean 在初始化时依赖的对象,这个对象会在这个Beam初始化之前创建 | ||
init-method | 用来定义Bean的初始化方法,它会在Bean 组装之后调用。它必须是一个无参数的方法 | ||
destroy-on | 用来定义Bean的销毁方法,它在BeanFactory 关闭时调用。同样,它也必须是一个无参数的方法。它只能应用于singleton Bean | ||
factroy-method | 定义创建该Bean对象的工厂方法。它用于下面的“factory-bean”,表示这个Bean是通过工厂方法创建。此时,“class”属性失效 | ||
factory-bean | 定义创建该Bean 对象的工厂类。如果使用了“factory-bean”则“class”属性失效 | ||
scope |
singleton prototype request session globalsession |
设置bean 的作用域request,session,global session仅用于Web 应用中 |
-
实例化上下文类
1 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("appSpring.xml");
-
getBean得到对象
1 Student student = (Student) applicationContext.getBean("stu"); 2 student.test();
name
分隔符是什么? 分隔符可以混用吗? 多个bean的name配置可以有相同的吗?
1 <!--别名使用空格,分号,逗号均可以,还可以混合使用,多个bean的name配置相同会报错--> 2 <bean id="stu" name="ss student,stus" class="com.Student"/>
配置的3种方式
-
直接class配置,实例化的是class代表的对象
-
工厂方法
-
factory-method
-
factory-bean factory-method ,factory-bean可以指向自己吗?
-
-
FactoryBean
作用域
singleton
Singleton :由容器管理对象的生命周期,也就是说容器存在,对象就创建出来(设定的init方法会执行,容器销毁,管理的对象也会销毁
当一个bean的 作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把 一个bean定义设置为singleton作用域时,Spring IOC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都 将返回被缓存的对象实例,这里要注意的是singleton作用域和GOF设计模式中的单例是完全不同的,单例设计模式表示一个ClassLoader中 只有一个class存在,而这里的singleton则表示一个容器对应一个bean,也就是说当一个bean被标识为singleton时 候,spring的IOC容器中只会存在一个该bean。
1 <bean id="role" class="spring.chapter2.maryGame.Role" scope="singleton"/> 2 或者 3 <bean id="role" class="spring.chapter2.maryGame.Role" singleton="true"/>
Prototype
Prototype:getBean的临时产生一个,产生之后的对象,spring容器就不管理,由程序自己去管理它的销毁
prototype作用域部署的bean,每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的 getBean()方法)都会产生一个新的bean实例,相当与一个new的操作,对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。 清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被singleton作用域bean占用资源的一种可行方式是,通过使用 bean的后置处理器,该处理器持有要被清除的bean的引用。)
1 <bean id="role" class="spring.chapter2.maryGame.Role" scope="prototype"/> 2 或者 3 <bean id="role" class="spring.chapter2.maryGame.Role" singleton="false"/>
全局的配置:
<beans default-init-method="开始方法名" default-destroy-method="销毁方法名"></beans>
调用销毁方法
((ConfigurableApplicationContext)applicationContext).close();
多配置文件
import
1 <!--appSpring.xml配置--> 2 <import resource="appSpring2.xml"></import> 3 4 <!--appSpring2.xml配置--> 5 <?xml version="1.0" encoding="UTF-8"?> 6 <beans xmlns="http://www.springframework.org/schema/beans" 7 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 8 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 9 10 <bean id="stu" class="com.Student"/> 11 </beans>
new xxx("","")
1 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("appSpring.xml","appSpring2.xml");
验证:每个文件里面配置一个beangetBean的时候都能得到
自己的POJO,比如service类,dao类,entity类
配置的元数据
xml
注解
你自己的POJO类
1 public class UserDao{ 2 public void insert(){----} 3 } 4 5 public class UserService{ 6 private UserDao dao; 7 8 //getter,setter 9 10 public void insert(){ 11 dao.insert(); 12 } 13 }元数据
1 <bean id="dao" class="UserDao"/> 2 <bean id="service" class="UserService"> 3 <property name="dao" ref="dao "></property> 4 </bean>容器类
1 ApplicationContext app = new ClassPath***ApplicationContext 2 app.getBean("service")1 UserService service = new UserService(); 2 service.insert();
HttpServletRequest,不能被spring容器管理,因为它是由Tomcat容器实例化
自己写的Servlet能被spring管理吗? 也不能被Spring管理,也就是说不是pojo
能被Spring管理的
- Service类型
- dao类型
- 控制器类型(比如Struts2里面的Action)