Spring配置文件
【对 第一个 HelloWorld 程序】 进行解刨知识点
1.Bean标签基本配置
用于配置对象交由Spring 来创建。 默认情况下它调用的是类中的无参构造函数,如果没有无参构造函数则不能创建成功。【这种方法叫做 无参方法实例化 Bean对象是根据它的无参构造来获取的】
基本属性: id:Bean实例在Spring容器中的唯一标识 【emm 唯一标识 真是个常识.】
class:Bean的全限定名称 【记得带包名 而且方法要有无参构造】
2.Bean标签范围配置
除了 Id 和 Class ,Bean标签还有一个属性 scope : 学过JSP都知道 是域、范围的意思.
scope:指对象的作用范围,取值如下:
取值范围 | 说明 |
singleton | 默认值,单例的 |
prototype | 多例的 |
request | WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中 |
session | WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中 |
global session | WEB 项目中,应用在 Portlet 环境,如果没有 Portlet 环境那么globalSession相当于 session |
所以 我们没配置 他就会 singleton 单的,我们先详说 singletion 和 prototype :
因为其他设计到了 WEB 项目:
Bean标签范围配置
1)当scope的取值为singleton时 Bean的实例化个数:1个 【无参构造 只执行一次】
Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例 【意思是说 emmmm 在获取到XML对象时 只执行一次无参构造 那么证明只实例化一次 以后都是同一对象 而且 只有一个Bean对象 因为是singleton 单例 】
Bean的生命周期: 对象创建:当应用加载,创建容器时,对象就被创建了 【出生】
对象运行:只要容器在,对象一直活着 【活着】
对象销毁:当应用卸载,销毁容器时,对象就被销毁了 【销毁】
2)当scope的取值为prototype时 Bean的实例化个数:多个 【实例化一个 就执行一次无参构造】
Bean的实例化时机:当调用getBean()方法时实例化Bean 【意思是说 emmmm 在获取到XML对象时 不会实例化 当 getBean 时 会执行无参构造一次 每一次都是不同的对象 不同的Bean】
对象创建:当使用对象时,创建新的对象实例
对象运行:只要对象在使用中,就一直活着
对象销毁:当对象长时间不用时,被 Java 的垃圾回收器回收了
例: 【Junit 测试:】
HelloServer.java : 【接口】
package com.bihu.helloDao;
public interface HelloService {
void show();
}
HelloServiceImpl.java : 【实现类】
package com.bihu.helloImpl;
import com.bihu.helloDao.HelloService;
public class HelloServiceImpl implements HelloService {
//无参构造:
public HelloServiceImpl() {
System.out.println("实例化了一个 HelloServiceImpl 对象 执行了无参构造");
}
public void show() {
System.out.println("Hello World!");
}
}
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">
<!-- 默认 singleton【单例】 自行更换 prototype【多例】 -->
<bean id="hello_bean" class="com.bihu.helloImpl.HelloServiceImpl" scope="singleton" ></bean>
</beans>
Test: 【一般测试类 都新建一个文件夹 Test 然后里面包都和 main 的差不多 其实就是 一个 java 一个 resource 】
import com.bihu.helloImpl.HelloServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
@Test //要导入 Junit 的 GAV
public void springTest(){
//获取XML
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
//实例化两个 HelloServiceImpl 对象:
HelloServiceImpl app1 = (HelloServiceImpl)app.getBean("hello_bean");
HelloServiceImpl app2 = (HelloServiceImpl)app.getBean("hello_bean");
//分别打印他的地址 如果在你spring配置文件中的Bean 是singleton 的话 地址会一样,如果是prototype的话 会不一样 其次执行的无参构造次数也不一样
// 所以可以根据它的特性来DEBUG:
System.out.println(app1);
System.out.println(app2);
}
}
所以 单例 和 多例的区别 就在这里 自己测试即可.
3. Bean生命周期配置
init-method:指定类中的初始化方法名称
destroy-method:指定类中销毁方法名称
直接在 Bean 中配 即可 ,但是确保 Bean中有函数存在,例:
当然名字你自己设置啊 自定义.
HelloServiceImpl.java
package com.bihu.helloImpl;
import com.bihu.helloDao.HelloService;
public class HelloServiceImpl implements HelloService {
//无参构造:
public HelloServiceImpl() {
System.out.println("实例化了一个 HelloServiceImpl 对象 执行了无参构造");
}
public void show() {
System.out.println("Hello World!");
}
/*--初始化 和 销毁 方法: --*/
public void init() {
System.out.println("Bean出生了");
}
public void destroy() {
System.out.println("Bean销毁了");
}
}
Spring配置文件:
<?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">
<!-- 默认 singleton【单例】 自行更换 prototype【多例】 -->
<bean id="hello_bean" class="com.bihu.helloImpl.HelloServiceImpl" scope="singleton" init-method="init" destroy-method="destroy" ></bean>
</beans>
测试: 当你单单获取xml 的话 他会执行 init方法 因为在spring中设置了
import com.bihu.helloImpl.HelloServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
@Test //要导入 Junit 的 GAV
public void springTest(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
}
}
它的输出:
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
实例化了一个 HelloServiceImpl 对象 执行了无参构造
Bean出生了
Process finished with exit code 0
但是 没执行销毁方法 因为 emmmm 没来得及打印....
如果你实在想去测试,那么:
import com.bihu.helloImpl.HelloServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
@Test //要导入 Junit 的 GAV
public void springTest(){
//ApplicationContext 改成了 ClassPathXmlApplicationContext,因为ClassPathXmlApplicationContext是ApplicationContext的实现类,所以有close方法.
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
app.close(); //关掉 所以就可以自动调用 销毁方法了
//这个理解即可 知道那个原理
}
}
输出:
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@574caa3f: startup date [Fri Jun 18 11:57:00 CST 2021]; root of context hierarchy
六月 18, 2021 11:57:00 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
实例化了一个 HelloServiceImpl 对象 执行了无参构造
Bean出生了
六月 18, 2021 11:57:00 上午 org.springframework.context.support.AbstractApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@574caa3f: startup date [Fri Jun 18 11:57:00 CST 2021]; root of context hierarchy
Bean销毁了
4.Bean实例化三种方式
1.无参构造方法实例化
2.工厂静态方法实例化
3.工厂实例方法实例化
第一种不多说 上面那个就是 无参构造方法实例化
工厂静态方法实例化:
说到工厂 就想起 factory ,就想到工厂模式,而且是静态的:
其实就是 返回一个指定的对象回去(工厂) ,然后在Spring配置文件中配置【Class变为 工厂模式的地址 、 添加 factory-method 字段,值是工厂类的方法【返回对象那个方法】】
其实就是反射,接下来看代码:
先创建一个静态工厂 这里是 StaticFactroy类:
package com.bihu.factroy;
import com.bihu.helloImpl.HelloServiceImpl;
//静态工厂
public class StaticFactroy {
public static HelloServiceImpl GetHelloServiceImpl(){
return new HelloServiceImpl();
}
}
然后我们配置Spring文件:
<?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="StaticFactory" class="com.bihu.factroy.StaticFactroy" factory-method="GetHelloServiceImpl"></bean>
</beans>
记住 静态工厂实例化模式是factory-method 一个就够!!!
然后我们测试:Test.java:
<?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="StaticFactory" class="com.bihu.factroy.StaticFactroy" factory-method="GetHelloServiceImpl"></bean>
</beans>
输出:
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
实例化了一个 HelloServiceImpl 对象 执行了无参构造
Hello World!
Process finished with exit code 0
证明是 毫无问题的 这种。
工厂实例方法实例化
刚刚是静态的 这次来个不是静态的:
想想看 既然是工厂实例方法 少不了创建工厂模式,但是由于不是静态的话 肯定要先获取到他的工厂实例 然后配置哪方面: 肯定要先有工厂Bean 那么就是 先创建一个工厂Bean 然后跟着这个工厂Bean进去找方法即可 完成实例化 Bean.
其中 在Spring的配置文件中 获取 工厂Bean 是:factory-bean 属性,值是 自己配的 工厂Bean,所以工厂Bean 相当于Class 。
所以大体思路 唯一要改的就是 Spring的配置文件 和 去掉静态方法 上代码:
package com.bihu.factroy;
import com.bihu.helloImpl.HelloServiceImpl;
//工厂模式实例化
public class StaticFactroy {
public HelloServiceImpl GetHelloServiceImpl(){
return new HelloServiceImpl();
}
}
去掉静态的啊 因为是工厂实例方法实例化...有点绕口..
然后是Spring 配置文件:
<?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">
<!--工厂实例化:-->
<!-- 因为不是静态的 所以先创建一个FactoryBean,在通过FactoryBean去反射找到指定的方法 实例化 Bean -->
<!-- 先获取工厂Bean: -->
<bean id="FactoryBean" class="com.bihu.factroy.StaticFactroy"></bean>
<!-- 然后根据工厂Bean获取指定方法获取Bean -->
<bean id="Bean" factory-bean="FactoryBean" factory-method="GetHelloServiceImpl" ></bean>
</beans>
其实这里的 FactoryBean 相当于 静态工厂模式的 Class .
说那么多 已经是很保姆级别的了 请带脑子阅读...
测试: Test.java :
import com.bihu.helloImpl.HelloServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
@Test //要导入 Junit 的 GAV
public void springTest(){
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloServiceImpl staticFactory = (HelloServiceImpl)app.getBean("Bean");
staticFactory.show();
}
}
Bean 差不多了... 主要还是要有反射思维...
注意: 不要看这里的包名 我乱打的!!! 和MVC模式对不上的!不是MVC模式!!! 你只需知道 一个接口 一个实现即可,因为是测试 所以没认真看包名.你只需要知道 那个是接口 那个是实现即可,真正的MVC模式命名和归类是很规范的.
完.
本文来自博客园,作者:咸瑜,转载请注明原文链接:javascript:void(0)p/14898630.html