声明,以下案例使用的JDK9,Spring-framework-5.0.9.RELEASE;
使用的依赖、约束、文档,这三个必须下载,解压后如下; spring官网下载地址如下;
http://repo.spring.io/release/org/springframework/spring/
整个spring框架的结构如下【该图是spring官网给出的】:
Spring的核心;
IoC(Inverse of Control 控制反转): 将对象创建权利交给Spring工厂进行管理。
AOP(Aspect Oriented Programming 面向切面编程),基于动态代理的功能增强方式。
配置XML文档地址;
怎么使用ioC容器呢?
它 ApplicationContext
是高级工厂的接口,能够维护不同bean及其依赖项的注册表。使用该方法,T getBean(String name, Class<T> requiredType)
您可以检索 Bean 的实例。
在 ApplicationContext
可以读取 bean 定义并访问它们,如下所示:
// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);
// use configured instance
List<String> userList = service.getUsernameList();
Spring框架使用的工厂类有2个;
BeanFactory和ApplicationContext 工厂类;
① ApplicationContext继承 顶级工厂类(接口)BeanFactory(比较老的工厂类,功能较弱) ,具有更强的功能 ;
前者在 getBean的时候初始化类的实例;
后者在管理时候初始化(加载配置文件时候);
② ApplicationContext 的 classpath... 和 fileSystem... 两个实现类;
前者src下的路径, 后者在硬盘下的路径;
(1)BeanFactory实现解耦合;
项目结构如下,其中 commons-logging-1.2jar 是日志 log.jar ;配置文件放在了config中【也可以放在src下】;
配置文件 beans.properties;
demoDao=com.company.daoImpl.DemoDaoImpl
demoService=com.company.serviceImpl.DemoServiceImpl
工具类 utils 中的 BeanFactory 类【注意getBundle(配置文件前缀)】;
package com.company.utils;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.ResourceBundle;
/**
* @auther SyntacticSugar
* @data 2018/9/22 0022下午 11:41
* <p>
* 编写factory 类 解耦,properties中(k,v)--->map(k,obj);
* //clazz.getDeclaredConstructor().newInstance()
*/
public class BeanFactory {
private static ResourceBundle rb = ResourceBundle.getBundle("beans");
private static HashMap<String, Object> map = new HashMap<>();
static {
try {
Enumeration<String> keys = rb.getKeys();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
String value = rb.getString(key);//转化成obj
Object bean = Class.forName(value).getDeclaredConstructor().newInstance();
map.put(key, bean);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static Object getBeans(String beanName) {
return map.get(beanName);
}
}
ServiceImpl层 :
package com.company.serviceImpl;
import com.company.daoImpl.DemoDaoImpl;
import com.company.service.DemoService;
import com.company.utils.BeanFactory;
/**
* @auther SyntacticSugar
* @data 2018/9/21 0021下午 12:00
*/
public class DemoServiceImpl implements DemoService {
@Override
public void showDemoService() {
// DemoDaoImpl daoImpl = new DemoDaoImpl();
DemoDaoImpl daoImpl = (DemoDaoImpl)BeanFactory.getBeans("demoDao");
daoImpl.showDemo();
}
}
web层:
package com.company.web;
import com.company.serviceImpl.DemoServiceImpl;
import com.company.utils.BeanFactory;
import org.junit.Test;
/**
* @auther SyntacticSugar
* @data 2018/9/21 0021下午 12:00
*/
public class DemoAdmian {
@Test
public void test01() {
// DemoServiceImpl service = new DemoServiceImpl();
DemoServiceImpl service =(DemoServiceImpl) BeanFactory.getBeans("demoService");
service.showDemoService();
}
}
运行下:
(2)ApplicationContext 实现解耦合;
要配置service.xml和dao.xml;
spring官网,配置XML文档地址;
参考官网5.09版本的 core文档 ,获取beans 依赖的约束,其中id是随便起个id名字【一般是哪一个class就是哪一个名字】,class是类在项目中的 全限定路径名;
其中,schema约束尾部的http地址用于配置XML约束【类似于DTD约束XML的设置效果一样】,引用的beans真实地址在spring框架的schema库的beans目录下;
http://www.springframework.org/schema/beans/spring-beans.xsd
或者,查看配置元数据【就是配置XML的数据结构的,随便找个例子copy个约束头即可】:
附上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">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
Spring IoC容器 管理一个或多个bean所以,传参可以传入单个参数或者多个参数,请参阅上面使用容器;
test类;
package com.company.test;
import com.company.serviceImpl.DemoServiceImpl;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @auther SyntacticSugar
* @data 2018/9/23 0023上午 11:07
*/
public class SpringTest {
@Test
public void test01(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("service.xml");
DemoServiceImpl demoService = (DemoServiceImpl)context.getBean("demoService");
demoService.showDemoService();
}
}
运行下:
bean类的生命周期【初始化init 和销毁】;
引用官网的两段解释,bean类的初始化和销毁方式有3种【注解,XML,实现接口】;注解开发 在现代实际应用spring开发实践中是最好的,@postConstructor 和 @PreDestroy 在bean 类的初始化和销毁上;其次使用XML配置,最后接口开发不建议使用【因为它会不必要地将代码耦合到 Spring】。
这里使用XML开发;
①bean类的初始化方法,这里使用XML配置的 init-method 和 destroy-method;
②说spring 的销毁方法 2 种,实现了closable接口的 close方法,或者shutdown方法【推荐使用后一种 registerShutdownHook()直接关闭 ioC 容器】;
bean生命周期配置;
<bean id="demoDao" class="daoImpl.DemoDaoImpl" init-method="setup" destroy-method="destory">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!--生命周期的配置-->
<!-- more bean definitions go here -->
测试类;
import dao.DemoDao;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @auther SyntacticSugar
* @data 2018/9/24 0024上午 12:14
*/
public class DemoTest01 {
@Test
public void test1(){
ClassPathXmlApplicationContext ct = new ClassPathXmlApplicationContext("applicationContext.xml");
DemoDao demoDao = (DemoDao) ct.getBean("demoDao");
demoDao.show();
ct.registerShutdownHook();
// ct.close();
}
}
运行;
常见的错误; 项目结构老跑到6;
常见错误;
Can't find bundle for base name beans.properties, locale zh_CN
是因为加载配置文件properties失败,常见原因2个;
①没在src目录下面【显然我没有错】;
②在传参是后名字出错;这里仅仅需要传入配置文件的 名字即可,例如bean.properties,仅仅传入bean就行。
出错处: