昨天看到了jjdk中的Proxy类和InvocationHandler接口可以实现动态代理,又联想到spring中的bean就是动态代理,所以尝试着写了一个通过动态代理实现的容器。
首先因为jdk中的动态代理代理的是接口,所以得先定义一个接口,以便具体类实现
接口CarAction:
package com.wq.BeanFactory;
public interface CarAction{
public void describer();
}
然后编写具体的类实现上面的接口(Car)
<pre name="code" class="java">package com.wq.BeanFactory;
import java.math.BigDecimal;
public class Car implements CarAction{
private String carname;
private double kilemeters;
public Car(){}
public String getCarname() {
return carname;
}
public void setCarname(String carname) {
this.carname = carname;
}
public double getKilemeters() {
return kilemeters;
}
public void setKilemeters(double kilemeters) {
this.kilemeters = kilemeters;
}
public Car(String name,double k){
this.carname=name;
this.kilemeters=k;
}
@Override
public void describer(){
BigDecimal bg=BigDecimal.valueOf(kilemeters);
System.out.println("The Car Name is : "+carname+".The Kilemeters is : "+bg.toString());
}
}
注意,该类中要有一个无参的构造方法,具体原因在后面
编写一个代理类,实现java.lang.reflect.*下的InvocationHandler接口
<pre name="code" class="java">package com.wq.BeanFactory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class proxyClass implements InvocationHandler{
private Object c;
public proxyClass(Object c){
this.c=c;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws IllegalAccessException,InvocationTargetException{
System.out.println("即将开始执行代理方法: "+method.getName());
Object result=method.invoke(c,new Object[0]);
System.out.println("代理方法:"+method.getName()+" 结束!");
return result;
}
}
编写一个配置文件,模仿spring中的ApplicationContext.xml。此处为properties
<pre name="code" class="plain">LandRover=com.wq.BeanFactory.Car
LandRover.carname=LandRover
LandRover.kilemeters=36.20
Porsche=com.wq.BeanFactory.Car
Porsche.carname=Porsche
Porsche.kilemeters=36.89
Lamborghini=com.wq.BeanFactory.Car
Lamborghini.carname=Lamborghini
Lamborghini.kilemeters=80.43
这些都有了,只剩下一个工厂类了 SpringFactory
<pre name="code" class="java">package com.wq.BeanFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Proxy;
import java.util.*;
public class SpringFactory {
Map<String,Object> carMap=new HashMap<>();
Map<String,Object> kvproperty=new HashMap<>();
Map<String,Object> finalEntity=new HashMap<>();
@SuppressWarnings("rawtypes")
public Object springFactory(String carname) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException{
File file=new File("E:\\SOFT\\IOC\\src\\com\\wq\\BeanFactory\\BeanFactory.properties");
FileInputStream fis=new FileInputStream(file);
Properties p=new Properties();
p.load(fis);
for(Map.Entry entry:p.entrySet()){
String key=entry.getKey().toString();
String value=entry.getValue().toString();
if(key.split("\\.").length>1){
//讲属性加入链表
kvproperty.put(key, value);
}else{
//得到无参构造出的实体,是object对象,放入map
carMap.put(key, getEntity(key,value));
}
}
//实体对象赋值完,调用代理类进行动态代理,并且存进映射表
List<Object> carlist=setProperty(carname);
for(Object obj:carlist){
proxyClass pc=new proxyClass((Car)obj);
//因为之前是代理的是接口,所以此处只能是接口实现
rAction cproxy=(CarAction)Proxy.newProxyInstance(
Car.class.getClassLoader(),Car.class.getInterfaces(), pc) ;
finalEntity.put(((Car)obj).getCarname(), cproxy);
}
fis.close();
//根据输入参数,得到映射表中的实体类
return finalEntity.get(carname);
}
//编写一个方法,为实体对象赋值
private List<Object> setProperty(String name){
List<Object> list=new ArrayList<>();
for(String objkey:carMap.keySet()){
Car ca=(Car) carMap.get(objkey);
String carname=(String) kvproperty.get(name+".carname");
double kl=Double.parseDouble((String) kvproperty.get(name+".kilemeters"));
ca.setCarname(carname);
ca.setKilemeters(kl);
list.add(ca);
}
return list;
}
//根据配置文件中的信,通过反射得到一个实体
private Object getEntity(String key,String value) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
Object obj=null;
//System.out.println(value);
<span style="white-space:pre"> </span>//因为下面的方法需要一个无参的构造函数
obj=Class.forName(value).newInstance();
//Class.forName(value).newInstance();
return obj;
}
}
测试类:
<pre name="code" class="java">package com.wq.BeanFactory;
import java.io.*;
public class DongtaiProxy{
public static void main(String args[]) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
//proxyCar();
//SpringFactory.springFactory();
CarAction ca=(CarAction) new SpringFactory().springFactory("Lamborghini");
ca.describer();
}
}
至此,通过动态代理实现简易容器就完成了