本示例通过生产者和消费者的例子演示如何通过普通编码实现spring的依赖注入
首先编写商品类、生产者、消费者代码如下
package my.spring.pojo;
public class Product {
public int serialno;
public String name;
public Product(int id){
setSerialno(id);
setName("product"+id);
}
public int getSerialno() {
return serialno;
}
public void setSerialno(int serialno) {
this.serialno = serialno;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package my.spring.pojo;
import java.util.List;
public class Producer {
private static int counter=0;
private int id;
public Producer(int id){
this.id=id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void produce(List<Product> products){
this.counter++;
Product product=new Product(counter);
products.add(products.size(),product);
System.out.println("producer:product"+counter+" current size:"+products.size());
}
}
package my.spring.pojo;
import java.util.List;
public class Consumer {
private int id;
public Consumer(int id){
this.id=id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void consume(List<Product> products){
if(products!=null && products.size()>0){
Product product=products.get(0);
System.out.println("consumer:product"+product.getSerialno()+" current size:"+products.size());
products.remove(0);
}
}
}
然后需要一个调度者统一管理生产者、消费者以及产品队列,因此需要将生产者、消费者注入调度者中
package my.spring.pojo;
import java.util.ArrayList;
import java.util.List;
public class Dispatcher {
private Producer producer;
private Consumer consumer;
private static List<Product> products;
public Dispatcher(){
this.products=new ArrayList<Product>();
}
public Dispatcher(Producer producer,Consumer consumer){
this.producer=producer;
this.consumer=consumer;
this.products=new ArrayList<Product>();
}
public void setProducer(Producer producer) {
this.producer = producer;
}
public void setConsumer(Consumer consumer) {
this.consumer = consumer;
}
public void dispatch(){
Thread thread1=new Thread(){
public void run(){
while(true){
producer.produce(products);
try {
int ms=(int) (Math.random()*1000);
sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
};
Thread thread2=new Thread(){
public void run(){
while(true){
consumer.consume(products);
try {
int ms=(int) (Math.random()*500);
sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
thread1.start();
thread2.start();
thread1.run();
thread2.run();
}
}
然后就要写实现类了
package my.spring.demo;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import my.spring.pojo.Consumer;
import my.spring.pojo.Dispatcher;
import my.spring.pojo.Producer;
public class CodeImpl {
public void run(){
// Producer producer=new Producer(101);
// Consumer consumer=new Consumer(24);
//
// Dispatcher dispatcher=new Dispatcher(producer, consumer);
// dispatcher.dispatch();
DefaultListableBeanFactory beanRegistry=new DefaultListableBeanFactory();
BeanFactory container=bindViaCode(beanRegistry);
Dispatcher dispatcher=(Dispatcher)container.getBean("dispatcherA");
dispatcher.dispatch();
}
public static BeanFactory bindViaCode(BeanDefinitionRegistry registry){
//设置生产者和消费者的构造器参数
ConstructorArgumentValues productArgumentValues=new ConstructorArgumentValues();
productArgumentValues.addIndexedArgumentValue(0,101);
ConstructorArgumentValues consumerArgumentValues=new ConstructorArgumentValues();
consumerArgumentValues.addIndexedArgumentValue(0,28);
AbstractBeanDefinition producer=new RootBeanDefinition(Producer.class,productArgumentValues,null);
AbstractBeanDefinition consumer=new RootBeanDefinition(Consumer.class,consumerArgumentValues,null);
AbstractBeanDefinition dispatcher=new RootBeanDefinition(Dispatcher.class);
registry.registerBeanDefinition("producerA", producer);
registry.registerBeanDefinition("consumerA", consumer);
registry.registerBeanDefinition("dispatcherA", dispatcher);
//通过构造器注入参数
ConstructorArgumentValues argumentValues=new ConstructorArgumentValues();
argumentValues.addIndexedArgumentValue(0, producer);
argumentValues.addIndexedArgumentValue(1, consumer);
dispatcher.setConstructorArgumentValues(argumentValues);
//通过setter方法注入
// MutablePropertyValues propertyValues=new MutablePropertyValues();
// propertyValues.addPropertyValue("producer", producer);
// propertyValues.addPropertyValue("consumer", consumer);
return (BeanFactory) registry;
}
}
通过单元测试运行可得
现对几个主要的类作简要说明:
例子中BeanFactory、BeanDefinationRegistry、DefaultListableBeanFactory的关系为
1、BeanDefination:定义的一个类实例(顶层接口),其中包含了属性(property)、构造器(constructor)等具体实现,为实现属性等元数据修改提供统一接口;
从包含的方法可知其定义了各种set和get类基本属性(类名、父类名、抽象、单例、延迟加载、描述、依赖、源定义类等等),功能十分强大。其直接继承的抽象类AbstrcatBeanFactory,再往下就是ChildBeanDefinition, GenericBeanDefinition, RootBeanDefinition,其中GenericBeanDefination比较常用。
2、BeanDefinationRegistry:BeanDefination的注册接口,说俗了也就是BeanDefination的一个容器,本身继承了AliasRegistry,即定义了对类别名操作函数;其子类DefaultListableBeanRegistry为最经典的类注册器,其中最为重要属性如下:
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
3、ConstructorArgumentValues:构造器的参数容器
private final Map<Integer, ValueHolder> indexedArgumentValues = new LinkedHashMap<Integer, ValueHolder>(0);
private final List<ValueHolder> genericArgumentValues = new LinkedList<ValueHolder>();
4、MutablePropertyValues:可变参数容器
private final List<PropertyValue> propertyValueList;
private Set<String> processedProperties;
private volatile boolean converted = false;