现在的位置: 首页 > 操作系统 > 正文

SpringIOC配置详解

2020年02月10日 操作系统 ⁄ 共 9637字 ⁄ 字号 评论关闭

1 IOC概述

1.1 IOC概念

IOC中文是控制反转,即是某一接口具体实现类的选择控制权从调用类中移除,转交给第三方决定。从而解除了某一接口对实现类的直接依赖。

1.2 IOC类型

主要分为构造函数注入,属性注入,接口注入

构造函数注入

public class Bar { private Foo foo; public Bar(Foo foo) { this.foo = foo; }}

属性注入

public class Bar { private Foo foo; public void setFoo(Foo foo) { this.foo = foo; }}

接口注入

public interface BarInterface { void setFoo(Foo foo);}

public class Bar implements BarInterface { private Foo foo; public void setFoo(Foo foo) { this.foo = foo; }}

此种方式和属性注入没有明显区别,但是却增加了一个接口,这不利于项目后期的维护,因此不建议使用!

1.3 spring的IOC配置

<?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="foo" class="org.acy.di.Foo"/> <bean id="bar" class="org.acy.di.Bar"> <property name="foo" ref="foo"/> </bean></beans>

2 spring的资源访问

2.1 资源抽象接口

Spring的Resource接口,使应用访问底层资源更加便捷。主要方法:-boolean exists() 是否存在-boolean isOpen()-URL getURL()-File getFile()-InputStream getInputStream()

这个接口下面主要的实现类有:

ByteArrayResource:内存资源ClassPathResource:类路径下的资源FileSystemResource:文件系统资源InputStreamResource:输入流资源ServletContextResource:Web容器上下文资源UrlResource:远程资源

测试1

public class FileSourceExample { public static void main(String[] args) { String filePath = "C:\\Users\\Administrator\\IdeaProjects\\spring\\c03\\src\\main\\resources\\1.txt"; Resource resource1 = new FileSystemResource(filePath); System.out.println(resource1.getFilename()); Resource resource = new ClassPathResource("1.txt"); System.out.println(resource.getFilename()); }}

测试2

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body><% Resource resource = new ServletContextResource(application, "/WEB-INF/classes/1.txt");%><%=resource.getFilename()%><%=WebUtils.getTempDir(application).getAbsolutePath()%></body></html>

测试3

public class EncodedTest { public static void main(String[] args) throws IOException { Resource resource = new ClassPathResource("1.txt"); EncodedResource encodedResource = new EncodedResource(resource,"utf-8"); String s = FileCopyUtils.copyToString(encodedResource.getReader()); System.out.println(s); }}

注:资源加载时默认采用系统编码读取资源,如果需要转码,可用EncodedResource

2.2资源加载

资源地址表达式

classpath: 从类的跟路径加载file: 从文件路径http: http协议ftp: ftp协议加载没有前缀 则根据当前实用的ApplicationConext实现类决定

"classpath*:"相对于"classpath:"的优势在于:如果有同包名的资源文件,分别打成了两个jar包【a.jar和b.jar】。用"classpath:"只加在a.jar中的资源文件。用"classpath*:"会加载a b两个jar包的配置文件

匹配符? :一个字符* :多个字符** :多级目录

资源加载器ResourceLoader:可以根据资源地址加载一个资源,但不支持匹配符ResourcePatternResolver:支持匹配符PathMatchingResourcePatternResolver:Spring的标准实现,也支持匹配符

public class ResolverTest { public static void main(String[] args) throws IOException { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = resolver.getResources("classpath*:org/acy/**/*.xml"); for (Resource resource : resources) { System.out.println(resource.getFilename()); } }}

3 BeanFactory与ApplicationContext

3.1 BeanFactory解读

BeanFactory是一个工厂,用于创造各种类型的对象。BeanFactory体系结构BeanFactory:底层接口ListableBeanFactory:增加访问容器中Bean基本信息的方法 如bean的个数,是否包含等。HierarchicalBeanFactory:父子容器级联接口,使子容器可以访问父容器。ConfigurableBeanFactory:重要接口,增强了IOC的定制化,加入了类装载器、属性编辑器、容器初始化后置处理器的方法AutowireCapableBeanFactory:加入自动装配

测试

public class BeanFactoryTest { public static void main(String[] args) { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource resource = resolver.getResource("classpath:applicationContext.xml"); BeanFactory beanFactory = new XmlBeanFactory(resource); System.out.println("BeanFactory 初始化完成"); Car car = beanFactory.getBean("car", Car.class); System.out.println(car); }}

注:以上使用了XmlBeanFactory,其为上面那些接口的最终实现类。用BeanFactory会导致Bean在容器启动时候不会主动初始化,而是等到第一次使用时候在初始化。

3.2 ApplicationContext介绍

主要实现类有ClasspathXmlApplicationContext与FileSystemXmlApplicationContext,且ApplicationContext所有实现类都实现了ResourcePatternResolver接口,可以接受匹配符表达式加载资源文件。并且ConfigurableApplicationContext还加入了refresh()和close(),用于刷新和关闭容器。ApplicationContext是在容器启动时初始化所有Bean

注解配置

@Configurationpublic class Beans { @Bean(name = "car") public Car buildCar() { Car car = new Car(); car.setBrand("三轮车"); car.setColor("red"); car.setMaxSpeed(200); return car; }}

public class AnnoTest { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(Beans.class); Car car = context.getBean("car", Car.class); System.out.println(car); }}

WebApplicationContextWebApplicationContext是存储在ServletContext中,所有可以再任何代码中取出实用。WebApplicationContextUtils.getWebApplicationContext(ServletContext sc)

WebApplicationContext初始化在Web.xml配置监听器ContextLoaderListener

<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>

如果不支持Listener,则可以使用ContextLoaderServlet

以上配置,Spring会默认采用XmlWebApplicationContext,如果要采用注解,可以实用如下配置

<context-param> <param-name>contextClass</param-name> <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> </context-param> <context-param> <param-name>contextConfigLocation</param-name> <param-value>org.acy.anno.Beans</param-value> </context-param>

4 Bean生命周期

Bean的作用范围实例化Bean时所经历的一系列阶段

4.1 BeanFactory的生命周期

关键点:

Bean自身的方法:如实例化,setter,或者init method和destroy methodBean级别生命周期接口方法: BeanNameAware BeanFactoryAware InitializingBean和DisposableBean重点 容器级生命周期接口方法 InstantiationAwareBeanPostProcessor和BeanPostProcessor,这些接口的实现类为单独的组件,实现后注册到容器上即可。[属于插件机制]

可以注册多个同种接口的实现类,但是必须实现Ordered接口排序。新版本中还加入了InstantiationAwareBeanPostProcessorAdapter抽象类

例子

public class Cat implements BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean { private String brand; private String color; private int maxSpeed; public Cat() { } public Cat(String brand, String color, int maxSpeed) { this.brand = brand; this.color = color; this.maxSpeed = maxSpeed; } public void introduce() { System.out.println(this.toString()); } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public int getMaxSpeed() { return maxSpeed; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } @Override public String toString() { return "Car{" + "brand='" + brand + '\'' + ", color='" + color + '\'' + ", maxSpeed=" + maxSpeed + '}'; } private BeanFactory beanFactory; public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("setBeanFactory"); this.beanFactory = beanFactory; } private String beanName; public void setBeanName(String s) { System.out.println("setBeanName"); this.beanName = s; } public void destroy() throws Exception { System.out.println("destroy"); } public void afterPropertiesSet() throws Exception { System.out.println("afterPropertiesSet"); } public void myInit(){ System.out.println("myInit"); this.setMaxSpeed(240); } public void myDestroy(){ System.out.println("myDestroy"); }}

public class MyBeanPostProcessor implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if ("cat".equals(beanName)) { Cat cat = (Cat) bean; if (cat.getColor() == null) { System.out.println("color 为空 设为黑色"); cat.setColor("black"); } } return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if ("cat".equals(beanName)) { Cat cat = (Cat) bean; if (cat.getMaxSpeed() > 200) { System.out.println("speed great then 200"); cat.setMaxSpeed(200); } } return bean; }}

public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { @Override public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException { if ("cat".equals(beanName)){ System.out.println("postProcessBeforeInstantiation"); } return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if ("cat".equals(beanName)){ System.out.println("postProcessAfterInstantiation"); } return true; } @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { if ("cat".equals(beanName)){ System.out.println("postProcessPropertyValues"); } return pvs; }}

public class BeanCycle { public static void main(String[] args) { Resource res = new ClassPathResource("applicationContext.xml"); XmlBeanFactory beanFactory = new XmlBeanFactory(res); ConfigurableBeanFactory configurableBeanFactory = beanFactory; configurableBeanFactory.addBeanPostProcessor(new MyBeanPostProcessor()); configurableBeanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor()); Cat cat = beanFactory.getBean("cat", Cat.class); System.out.println(cat); cat.setColor("yellow"); Cat c2 = beanFactory.getBean("cat", Cat.class); System.out.println(cat == c2); beanFactory.destroySingletons(); }}

以上例子简单打印了一些spring的生命周期信息,并且有一些先后顺序。在新版本中 init method和destroy method的配置改为@PostConstruct和@PreDestroy注解配置。BeanPostProcessor是一个扩展Spring的重要接口。

4.2 ApplicationContext的生命周期

加入了一个新接口ApplicationContextAware 用户注入ApplicationContext。

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinition beanDefinition = beanFactory.getBeanDefinition("cat"); beanDefinition.getPropertyValues().addPropertyValue("brand","奇瑞qq"); System.out.println("postProcessBeanFactory"); }}

BeanFactoryPostProcessor实在最开始执行的,可以在对象实例化后,有线修改。在Bean被Spring加载后,会生成一个BeanDefinition

<bean id="cat" class="org.acy.bfc.Cat" init-method="myInit" destroy-method="myDestroy"> <property name="brand" value="奔驰"/> <property name="color" value="黑色"/> <property name="maxSpeed" value="200"/> </bean> <bean class="org.acy.bfc.MyBeanPostProcessor"/> <bean class="org.acy.bfc.MyBeanFactoryPostProcessor"/>

此处配置了一些Processor,ApplicationContext在启动时候会自动加载这些Processor。

本文永久更新链接地址:http://www.xuebuyuan.com/Linux/2017-03/141257.htm

以上就上有关SpringIOC配置详解的相关介绍,要了解更多Spring IOC,Spring IOC 配置详解,编程,Linux编程,Linux Shell,Android,Android教程,JAVA,C语言,Python,HTML5内容请登录学步园。

抱歉!评论已关闭.