前言
Spring IOC管制反转是通过反射机制与工厂模式的联合,上面给大家模仿一下
生存案例引入
2000 年,你们家开了一家叫 “笑笑” 的包子铺 ------爸
2002 年,你们城东新开了一家分店 “笑笑” 包子铺------妈
2004 年,你们城西也新开了一家分店"笑笑" 包子铺-----你
…
多年后,包子铺越开越多,口味难以保障
…
“笑笑” 包子铺老板:当前咱们几个外围班子只在一家做包子,所有分店不在做包子,间接来咱们这里提货即可
带来的益处:
1、所有包子铺的口味统一
2、所有包子铺不在关注做包子,只卖,做包子的过程(管制权限)–某一个工厂外面—IOC(Spring的管制反转)------>工厂模式
代码案例
构建污浊类
public class Book { private String name; private String author; private double price; public Book (){} @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", author='" + author + '\'' + ", price=" + price + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public Book(String name, String author, double price) { this.name = name; this.author = author; this.price = price; }}class AB extends Book{}class AC extends Book{}
传统形式构建实例
//1、传统形式 //弊病:须要本人构建对象(new),若我的项目中有几百个类,通过该形式构建实例不可取 Book b1 = new AB(); Book b2 = new AC();
污浊类的工厂类BookFactory
public class BookFactory { //应用简略反射降级 public static Book getBook1() throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //1、先应用反射获取Book的Class对象 Properties pro = new Properties(); //2、获取配置文件信息,加载配置文件 pro.load(new FileInputStream("D://JavaServletProject//ServletDemo//ZhenAiDemoVersionTwo//src//org//soffteem//sources//book//book.properties")); //3、失去配置文件外面的key值,依据key值反射失去class对象 Class<Book> bookClass = (Class<Book>)Class.forName(pro.getProperty("className")); //4、获取有参结构器 Constructor<Book> cons = bookClass.getDeclaredConstructor(String.class,String.class,double.class); //5、通过反射构建对象实例 return cons.newInstance(pro.getProperty("name"),pro.getProperty("author"),Double.parseDouble(pro.getProperty("price"))); } //如果用户过去须要书,会依据类名去构建书对象,原始办法 public static Book getBook(String name){ Book book = null; if (name.equals("AB")){ b = new AB(); }else if (name.equals("AC")){ b = new AC(); }else { //....如果有很多的书籍屡次断定..... } return book; }}
传统形式上降级
//2、当初有了笑笑包子铺(污浊类工厂)//弊病:此时不须要构建对象,然而仍然须要手动输出对象名称 System.out.println("请您输出须要的书名"); //....此处省略局部代码...... Book book = BookFactory.getBook("你输出的名字");
通过简略反射降级
className=org.soffteem.myspring.Bookauthor=王大锤name=倚天屠龙记price=38.9
//3、不必输出就能构建对象//弊病:如果不是Book对象而是其余对象呐?调用该工厂的这个办法只可能返回Book对象System.out.println("获取书籍:" + BookFactory.getBook1());
相似Spring IOC容器的工厂构建
XML文件
<?xml version="1.0" encoding="utf-8" ?><beans> <!--书籍类--> <bean id="book" class="org.soffteem.myspring.Book"> <property name="name" value="倚天屠龙记"></property> <property name="author" value="金庸"></property> <property name="price" value="25.3"></property> </bean> <!--各种其余类--> <!--此处的student类没有展现--> <bean id="student" class="org.soffteem.test.Student"></bean></beans>
相似"Spring IOC容器"类
public class ApplicationContextUtils { //文档对象 Document document; //1、初始化文档对象 public ApplicationContextUtils() throws DocumentException { //1.1 通过dom4j的jar读取xml文件,获取文档对象 SAXReader reader = new SAXReader(); this.document = reader.read("D://JavaServletProject//ServletDemo//ZhenAiDemoVersionTwo//src//org//soffteem//sources//book//books.xml"); } //2、反射 + 汇合 + xml解析 获取Bean实例 public <T>T getBean(String id,Class<T> tc) throws ClassNotFoundException, IllegalAccessException, InstantiationException { //2.1 解析xml文件,获取根节点 <beans><beans> Element element = document.getRootElement(); //2.2 获取根节点(<beans>)所有的子节点 <bean></bean> List<Element> list = element.elements(); //3、迭代所有的<bean>节点 for (Element e:list){ //3.1 失去<bean>子节点中id的值 String myId = e.attributeValue("id"); //3.2 失去<bean>子节点中class的数值 String className = e.attributeValue("class"); //3.3 断定:依据用户输出的id进行指定的实例化 //因为此处可能不只只有一个污浊类的节点配置项,要依据用户输出的id值实例化执行的配置节点 if (myId.equals(id)){ //3.3.1 反射以后id对应的className的class对象 Class c = Class.forName(className); //3.3.2 再次断定:若是父类呐?此处判断父类我是通过class对象断定的 if (c == tc){ //3.3.3 通过反射构建对象 T obj = tc.newInstance(); //3.3.4 失去以后<bean>节点中的所有<properties>子节点 List<Element> props = e.elements(); //3.3.5 失去所有的孙子节点对象<properties> for (Element prop:props){ //3.3.5.1 失去孙子节点的每一个属性内容name与value对应的值 String name = prop.attributeValue("name"); String value = prop.attributeValue("value"); //3.3.5.2 将内容赋值到对象属性中 setAttribute(tc.getDeclaredFields(),obj,name,value); } //返回对象 return obj; } } } return null; } //封装给属性赋值的办法 //① 须要失去所有的属性 ② 给哪个对象赋值 ③ 给哪个属性赋值 ④赋值的内容 public <T>void setAttribute(Field[] fields,T obj,String key,String value) throws IllegalAccessException { //1、循环属性,失去具体的属性值 for (Field field:fields){ //2、要想给属性赋值,因为属性是公有的,须要设置属性的拜访权限 field.setAccessible(true); //3、考虑一下属性的类型:根本属性类型、对象类型 Class type = field.getType();//获取以后属性字段field的类型 //此处我只写了几个根本数据类型,其余类型可自行添加...... if (key.equals(field.getName())){ if (type == int.class){ field.set(obj,Integer.parseInt(value)); }else if (type == double.class){ field.set(obj,Double.parseDouble(value)); }else if (type == String.class){ field.set(obj,value); }else { //若是对象类型 field.set(obj,value); } } } }}
模仿"Spring容器"构建实例
//1、构建 "Spring容器" 最先实例化可通过on-load-startup属性,前期交给tomcat容器ApplicationContextUtils application = new ApplicationContextUtils();//2、通过"Spring容器"联合配置文件的Id属性值获取Book对象Book book = application.getBean("book",Book.class);//3、格式化输入对象,进行内容展现System.out.println(book.toString());
模仿"Spring容器"构建实例步骤总结
- 构建污浊类,也就是JavaBean类
- 构建工厂类,便于JavaBean通过工厂创立实例
- 实例化工厂,调用工厂类的办法获取实例对象
- Spring IOC获取实例步骤总结
- 构建污浊类
- 构建Spring框架的配置文件
- 将污浊类注入到配置文件中
- 实例化Spring容器,通过getBean()办法依据Id属性值来获取对应的实例
最初
欢送关注公众号:前程有光,支付一线大厂Java面试题总结+各知识点学习思维导+一份300页pdf文档的Java外围知识点总结! 这些材料的内容都是面试时面试官必问的知识点,篇章包含了很多知识点,其中包含了有基础知识、Java汇合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日记、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构等等。