Spring Ioc 之Service Provider
本章目的
介绍IOC基本概念及职能,还有就是相关demo的编写。
干什么的
IOC的是控制反转,那么我们只要去声明我们需要的自有人为我们解决这个依赖的问题。我们就可以将精力集中在业务逻辑上,而Service Provider的职责是什么呢,就是你声明了 我去帮你将依赖设置进去,干这个脏活累活的角色就叫Service Provider了。
职责
1.创建对象 要单独拿出来防止污染客户端(a对象需要b对象 那b对象的创建应该交给IOC service Provider)
2.管理对象之间的依赖关系
如何管理对象之间的依赖关系
代码依赖
伪代码啊,不管是Spring还是Google的Guide都提供了这种方式。
IOCContainer ioccontainer = ...
ioccontainer.regiseter(A.class,new A());
ioccontainer.regiseter(B.class,new B())
A a = ioccontainer.getBean(A.class);
xml依赖配置
spirng的xml配置我相信大伙都是相当熟悉啊
<bean id= "a" class="....A">
<property name="bi" >
<ref bean="b">
</property>
</bean>
<bean id= "b" class="....B">
</bean>
元数据
测试类:
public static void main(String[] args) {
Injector inject = Guice.createInjector(new NewBandingModel());
NewProvider provider = inject.getInstance(NewProvider.class);
provider.getAndPersisterNews("1");
}
NewBandingModel类:
public class NewBandingModel implements Module {
@Override
public void configure(Binder binder) {
binder.bind(NewListener.class).to(TTNewListener.class);
binder.bind(NewPersister.class).to(NewPersisterImpl.class);
}
}
NewProvider 类:
public class NewProvider {
private NewListener newListener;
private NewPersister newPersister;
@com.google.inject.Inject
public NewProvider(NewListener listener,NewPersister newPersister){
this.newListener = listener;
this.newPersister = newPersister;
}
public void getAndPersisterNews(String newId){
NewComp comp = newListener.get(newId);
newPersister.persister(comp);
}
}
这里就是利用Google的Guide框架通过元数据完成依赖管理。
案例(demo)
相关pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lcy</groupId>
<artifactId>springlearning</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<springversion>5.1.4.RELEASE</springversion>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springversion}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springversion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springversion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${springversion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${springversion}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${springversion}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.inject/guice -->
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
公共用到的类
//在ioc使用过程中用到的类
public interface NewListener {
NewComp get(String newId);
}
public class TTNewListener implements NewListener {
@Override
public NewComp get(String newId) {
NewComp comp = new NewComp();
comp.setNewId(newId);
comp.setNewContent("来至头条");
return comp;
}
}
public interface NewPersister {
public void persister(NewComp newComp);
}
public class NewPersisterImpl implements NewPersister {
@Override
public void persister(NewComp newComp) {
System.out.println(newComp.getNewId()+":"+newComp.getNewContent());
}
}
@Data
public class NewProvider {
private NewListener newListener;
private NewPersister newPersister;
public NewProvider(NewListener listener,NewPersister newPersister){
this.newListener = listener;
this.newPersister = newPersister;
}
public void getAndPersisterNews(String newId){
NewComp comp = newListener.get(newId);
newPersister.persister(comp);
}
}
beanfactory
ioc 业务类的创建管理及对象注入管理 具体的某个实现类
以下为使用代码完成注册及注入代码
public static BeanFactory bandingByCode(){
DefaultListableBeanFactory register = new DefaultListableBeanFactory();
return registerByCode(register);
}
private static BeanFactory registerByCode(DefaultListableBeanFactory register) {
AbstractBeanDefinition listenerBeanDefinition = new RootBeanDefinition(TTNewListener.class);
AbstractBeanDefinition persisterBeanDefinitiontener = new RootBeanDefinition(NewPersisterImpl.class);
ConstructorArgumentValues cau = new ConstructorArgumentValues();
cau.addIndexedArgumentValue(0,listenerBeanDefinition);
cau.addIndexedArgumentValue(1,persisterBeanDefinitiontener);
AbstractBeanDefinition beanDefinition = new RootBeanDefinition(NewProvider.class,cau,null);
register.registerBeanDefinition("newListener",listenerBeanDefinition);
register.registerBeanDefinition("newPersister",listenerBeanDefinition);
register.registerBeanDefinition("newProvider",beanDefinition);
return register;
}
以上是通过代码完成注册 BeanDefinition 是记录一些类的元数据,BeanDefinitionRegister是注册类到容器的(货架),BeanFactory是获取相关类信息的(物品)。
###以下为xml方式完成Bean注册及注入代码
public abstract class BeanRegisterTem {
public void testRegister(String newId){
BeanFactory beanFactory = bandingRegster();
NewProvider provider = (NewProvider) beanFactory.getBean("newProvider");
provider.getAndPersisterNews(newId);
}
public BeanFactory bandingRegster(){
DefaultListableBeanFactory register = new DefaultListableBeanFactory();
return registerAlg(register);
}
public abstract BeanFactory registerAlg(BeanDefinitionRegistry register);
}
/**
* xml注册类继承模板类
*/
public class XmlRegister extends BeanRegisterTem{
@Override
public BeanFactory registerAlg(BeanDefinitionRegistry register) { //解析读取xml文件的主要业务类
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(register);
reader.loadBeanDefinitions("classpath:beantestconfig/beantestconfig.xml");
return (BeanFactory) register;
}
}
//测试代码
public static void main(String[] args) {
BeanRegisterTem brt = new XmlRegister();
brt.testRegister("5");
}
//控制台输出 5:来至头条
基于注解的方式
在java 5 spring2.5之前 是不支持注解的,所以BeanFactory在spring2.5以前是不支持注解方式进行依赖的创建及注入。
所以代码和配置文件有所变动 首先配置文件
<context:component-scan base-package="com.lcy.ioc.spring.registerandinject"/>
接着是类:
@Component
@Data
public class NewProvider {
@Autowired
private NewListener newListener;
@Autowired
private NewPersister newPersister;
public NewProvider(NewListener listener,NewPersister newPersister){
this.newListener = listener;
this.newPersister = newPersister;
}
public void getAndPersisterNews(String newId){
NewComp comp = newListener.get(newId);
newPersister.persister(comp);
}
}
同样另外两个listener和persister也添加上@Component用于扫描,注册。
最后测试方法:
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beantestconfig/beantestconfig.xml");
NewProvider newProvider = applicationContext.getBean(NewProvider.class);
newProvider.getAndPersisterNews("6");
}