简单模拟下ssm,复习动态代理
来源:互联网 发布:java泛型类 编辑:程序博客网 时间:2024/06/05 23:40
最近在学ssm,好奇底层是怎么实现的,
就根据现在所学的模拟了个,
顺便复习下动态代理,
时间紧,写的略渣
lib
dom4j-1.61.jar
xml
my.xml
<?xml version="1.0" encoding="UTF-8"?><peoples><people id="lihua"><property name="Name" value="lihua" type="java.lang.String"></property><property name="Age" value="19" type="java.lang.Integer"></property></people><people id="xiaomei"><property name="Name" value="xiaomei" type="java.lang.String"></property><property name="Age" value="19" type="java.lang.Integer"></property></people></peoples>
play.xml
<?xml version="1.0" encoding="UTF-8"?><plays><play id="sleep"><property value="10h" type="java.lang.String"></property></play><play id="eat"><property value="shi" type="java.lang.String"></property></play></plays>
用来模拟ioc根据配置文件创建对象
people.java
public interface People {public void eat(User u);public void sleep(User u);}
用来模拟动态代理根据配置文件实现mapper接口
User.java
public class User {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String toString() {return "user [name=" + name + ", age=" + age + "]";}}
main
import java.io.File;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Map.Entry;import java.util.Set;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;public class Test { public static void main(String[] args) throws Exception { //模拟ioc,根据配置文件实例化对象 User u = newBean("xml/my.xml","lihua"); //模拟动态代理实现dao接口//只是纯接口的动态代理没加jdbc People daili = (People)daili("xml/play.xml",People.class); daili.sleep(u); daili.eat(u); } /** * bean传给service根据 xml配置的事件动态代理dao接口 * @param path 配置文件地址 * @param c 需要代理的接口 * @return 代理实现的类 * @throws DocumentException */ private static Object daili(String path,Class<?> c) throws DocumentException {//代理类 SAXReader reader = new SAXReader(); Document document = reader.read(new File(path));//参数1:配置文件位置 Element element = document.getRootElement(); List<Element> elements = element.elements("play"); final Map<String,Map<String,String>> map=new HashMap();//这里先遍历配置文件储存,因为用集合取数据方便,也可以边读接口边根据xml实现接口 Map<String,String> ma=null; for (Element pl : elements) { ma=new HashMap(); String name = pl.attributeValue("id");//方法名 List<Element> para = pl.elements("property"); for (Element p : para) { String value = p.attributeValue("value");//参数值的string状态 String type = p.attributeValue("type");//参数类型的类 ma.put(value, type); } map.put(name, ma); }InvocationHandler h =new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String name = method.getName(); User u=(User)args[0]; Set<Entry<String,Map<String,String>>> set = map.entrySet(); for(Entry<String, Map<String, String>> entry:set){ if(entry.getKey().equals(name)&&name.contains("sleep")){ Set<Entry<String, String>> value = entry.getValue().entrySet(); for (Entry<String, String> v: value) { String para = v.getKey();//依次取出参数,这里只有一个就不判断了 String type = v.getValue();//因为直接打印就不转换回去了,需要的话自行转换 System.out.println(u.getName()+"今年"+u.getAge()+"岁,一天睡"+para); } } if(entry.getKey().equals(name)&&name.contains("eat")){ Set<Entry<String, String>> value = entry.getValue().entrySet(); for (Entry<String, String> v: value) { String para = v.getKey();//依次取出参数,这里只有一个就不判断了 String type = v.getValue();//因为直接打印就不转换回去了,需要的话自行转换 System.out.println(u.getName()+"今年"+u.getAge()+"岁,喜欢吃"+para); } } } return null; }}; return Proxy.newProxyInstance(Test.class.getClassLoader(), new Class<?>[]{c}, h); }/** * 通过xml配置的id来实例化一个对象 * @param path xml位置 * @param id xml中的id * @return 实例化好的bean对象 * @throws Exception */ private static User newBean(String path,String id) throws Exception { SAXReader reader = new SAXReader(); Document document = reader.read(new File(path));//参数1:配置文件位置 Element element = document.getRootElement(); List<Element> peoples = element.elements("people"); Element people=null; for (Element peo : peoples) { if(peo.attributeValue("id").equals(id))//参数1:id people=peo; } if(people==null){ System.out.println("配置文件中无此id"); System.exit(0); } List<Element> attrs = people.elements("property"); Class<?> user = Class.forName("dydaili.User"); Method[] methods = user.getMethods(); Map<String,Class<?>[]> map=new HashMap(); for (Method method : methods) {//获取bean的所有方法和参数类型 String name = method.getName(); Class<?>[] parameters = method.getParameterTypes(); map.put(name, parameters); }//后面有解释 User u=(dydaili.User) user.newInstance(); for (Element attr : attrs) { String name = attr.attributeValue("name");//属性名 String value = attr.attributeValue("value");//属性的值 String type =attr.attributeValue("type");//属性类型 Constructor c1 = Class.forName(type).getDeclaredConstructor(String.class);//获取常用类型构造,把string转换为对应类型 Method method = user.getMethod("set"+name,map.get("set"+name));//获取set方法,不用 Class.forName(type)而用map.get("set"+name)可以避免int和integer不匹配而找不到方法 method.invoke(u, c1.newInstance(value)); } return u; }}
难点在反射实例化类时,set方法是int型而配置文件是integer,于是找不到set方法,只好先获取了所有方法信息,只根据方法名去找方法,配置文件给的类型只用来转换值的类型
阅读全文
0 0
- 简单模拟下ssm,复习动态代理
- java动态代理原理及简单模拟
- java动态代理原理及简单模拟
- CGlib动态代理复习
- 再复习下java动态代理的过程
- 一个简单的例子模拟JDK动态代理
- 模拟java动态代理
- JDK 动态代理 模拟
- 模拟JDK动态代理
- 模拟JDK动态代理
- 模拟JDK动态代理
- JAVA动态代理模拟
- 简单模拟Spring AOP功能 (2) JDK动态代理技术和CGLib的动态代理
- java复习之动态代理
- ssm连表查询Mapper动态代理
- 模拟JDK动态代理 ; 自己动手模拟实现java动态代理
- 模拟JDK动态代理实现
- 模拟实现JDK动态代理
- Ajax的工作原理
- 如何禁止在WINDOWS上复制粘贴文件
- Servlet初识
- maven项目基础
- Java中的内部类(三)
- 简单模拟下ssm,复习动态代理
- leetcode刷题——
- 三、计算机网络之网际层
- 【matlab】蚁群算法详解
- python requests的方法
- eclipse开发RCP之三
- 程序片段----友元 friend
- vue学习中的一些总结
- new用法详解