簡單來說就是當自己需要一個對象的時候不需要自己手動去new一個,而是由其他容器來幫你提供;Spring裏面就是IOC容器。
例如:
在Spring裏面經常需要在Service這個裝配一個Dao,一般是使用@Autowired 等註解:
首先遍歷指定的包名:
1、調用構造方法自動初始化
2、jdom2讀取配置bean.xml,
3、通過讀取配置的bean.xml反射實例化讀取的配置文件中的類和service;
cmd
進入E 盤
E:
進入相關文件目錄
cd /src/main/java/com/spring
tree /f
tree /f F:\...\src\main\java\com\spring
------------------------------------------com.spring 包下文件結構
│ beans.xml
│ ClassPathXmlApplicationContext.java
│ UserServiceTest.java
│
├─dao
│ │ UserDAO.java
│ │
│ └─impl
│ UserDAOImpl.java
│
├─model
│ User.java
│
├─service
│ UserService.java
│
└─spingmn
BeanFactory.java
/*-------------------------------------------------------------------------------------------------------------------*/
UserDAO.java
package com.spring.dao;
import com.spring.dao.impl.UserDAOImpl;
import com.yang.dao.UserDao;
/**
* Created by Neusoft on 2019/10/21.
*/
public interface UserDAO {
public UserDao save(Object o);
}
/*-------------------------------------------------------------------------------------------------------------------*/
//UserDAOImpl.java
package com.spring.dao.impl;
import com.spring.dao.UserDAO;
import com.yang.dao.UserDao;
/**
* Created by Neusoft on 2019/10/21.
*/
public class UserDAOImpl implements UserDAO {
@Override
public UserDao save(Object o) {
System.out.println("調用DAO層 Save...");
return null;
}
}
/*-------------------------------------------------------------------------------------------------------------------*/
//User.java
package com.spring.model;
/**
* Created by Neusoft on 2019/10/21.
*/
public class User {
private long id;
private String name;
private String PWD;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPWD() {
return PWD;
}
public void setPWD(String PWD) {
this.PWD = PWD;
}
}
/*-------------------------------------------------------------------------------------------------------------------*/
//UserService.java
package com.spring.service;
import com.spring.model.User;
import com.spring.dao.UserDAO;
/**
* Created by Neusoft on 2019/10/21.
*/
public class UserService {
private UserDAO userDAO;
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public void add(User u){
this.userDAO.save(u);
}
}
/*-------------------------------------------------------------------------------------------------------------------*/
//BeanFactory.java 重點面向接口編程
package com.spring.spingmn;
/**
* Created by Neusoft on 2019/10/21.
*/
public interface BeanFactory {
public Object getBean(String name);
}
/*-------------------------------------------------------------------------------------------------------------------*/
//beans.xml
<beans>
<bean id="u" class="com.spring.dao.impl.UserDAOImpl"/>
<bean id="userService" class="com.spring.service.UserService">
<property name="userDAO" bean="u"/>
</bean>
</beans>
/*-------------------------------------------------------------------------------------------------------------------*/
//ClassPathXmlApplicationContext.java 用jdk反射實現xml 配置的類 IOC-》DI
package com.spring;
import com.spring.spingmn.BeanFactory;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import java.awt.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Created by Neusoft on 2019/10/21.
*/
public class ClassPathXmlApplicationContext implements BeanFactory{
private Map<String,Object> beans = new HashMap<String,Object>();
public ClassPathXmlApplicationContext() throws Exception {
System.out.println("jdom2 解析xml文件 :\n");
//創建一個解析器
SAXBuilder saxBuilder = new SAXBuilder();
//將流加載到解析器中。
//Document document = saxBuilder.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml"));
Document document = saxBuilder.build(this.getClass().getResource("").getPath()+"beans.xml"); //可能需手動將文件放入class 文件夾
//獲取文檔的根節點
Element root=document.getRootElement();
//將根節點的所有子節點獲取放到一個集合中
List list=root.getChildren("bean");
//循環遍歷所有子節點
System.out.println("外循環次數======"+(list.size()+1));
for (int i = 0; i < list.size(); i++) {
Element element=(Element)list.get(i);
String id=element.getAttributeValue("id");
String clazz=element.getAttributeValue("class");
System.out.println("id=== "+id);
System.out.println("clazz=== "+clazz);
System.out.println("id:clazz "+id+":" +clazz);
/*
Class.forName(String className)這個方法傳入一個類型的全路徑的名字(也就是帶包的完整名字),會返回一個字節碼類型(也就是Class類型)的實例
如:Class clazz = Class.forName("com.dean.Person");
然後再用這個字節碼類型的實例clazz調用newInstance()方法會返回一個Object類型的對象
這個object當然不能直接調用Perosn類的方法了,因爲他是Object類型
這個時候就需要強制類型轉換了
Person person = (Perosn)clazz.newInstance();
*/
Object O=Class.forName(clazz).newInstance();
System.out.println("O=== "+O);
beans.put(id,O); //放入map
System.out.println("T1"+element.getChild("property"));
System.out.println("T2"+element.getChildren("property"));
System.out.println("內循環次數======"+(element.getChildren("property").size()+1));
for (Element propertyElement:(List<Element>)element.getChildren("property")) {
String name = propertyElement.getAttributeValue("name"); //userDAO
String bean = propertyElement.getAttributeValue("bean"); //u
Object beanObject=beans.get(bean); //UserDaoImpl instance
System.out.println("beanObject===="+beanObject);
String methodName="set"+name.substring(0,1).toUpperCase()+name.substring(1);
System.out.println("T4 method name="+methodName);
//獲得對象所聲明的公開方法
//該方法的第一個參數name是要獲得方法的名字,第二個參數parameterTypes是按聲明順序標識該方法形參類型
Method method=O.getClass().getMethod(methodName,beanObject.getClass().getInterfaces()[0]);
System.out.println("獲取第一個類方法 method== "+method);
//傳入要執行的實體類 和 執行的方法對應的參數 Object i = method.invoke(new AA(), 1,2);
Object omi = method.invoke(O,beanObject);
// O=com.spring.service.UserService@1786e64
// beanObject====com.spring.dao.impl.UserDAOImpl@1c1ea29
System.out.println();
}
}
}
@Override
public Object getBean(String name) {
//使用Iterator遍歷
Iterator iter = beans.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
}
return beans.get(name);
}
public void readXML() throws Exception{
try {
//創建一個解析器
SAXBuilder builder=new SAXBuilder();
//創建一個文件輸入流
InputStream in=new FileInputStream(this.getClass().getResource("").getPath()+"beans.xml");
//將流加載到解析器中。
Document document=builder.build(in);
//獲取文檔的根節點
Element rootElement=document.getRootElement();
//將根節點的所有子節點獲取放到一個集合中
List<Element> list=rootElement.getChildren();
//循環遍歷所有子節點
for(Element element:list){
System.out.println("開始遍歷第"+(list.indexOf(element)+1)+"節點======");
//獲取所有的屬性並遍歷輸出
List<Attribute> list1=element.getAttributes();
for(Attribute attr:list1){
System.out.println("屬性名是:"+attr.getName());
System.out.println("屬性值是:"+attr.getValue());
}
System.out.println("結束遍歷第"+(list.indexOf(element)+1)+"節點======");
}
}catch (IOException e){
//打印輸出異常
e.printStackTrace();
}
finally{
System.out.println("如調試運行異常需將beans.xml複製到相關class 目錄下");
}
}
}
/*-------------------------------------------------測試類------------------------------------------------------------------*/
//UserServiceTest.java
package com.spring;
import com.spring.dao.UserDAO;
import com.spring.dao.impl.UserDAOImpl;
import com.spring.model.User;
import com.spring.service.UserService;
import com.spring.spingmn.BeanFactory;
import org.junit.Test;
/**
* Created by Neusoft on 2019/10/21.
*/
public class UserServiceTest {
@Test
public void testAdd_old1() throws Exception {
System.out.println("當前執行方法 " + this.getClass().getSimpleName()+ ":" + new Exception().getStackTrace()[0].getMethodName());
UserService userService = new UserService(); //new 出服務
UserDAO userDAO = new UserDAOImpl(); //new DAO層實現
userService.setUserDAO(userDAO);
User user = new User();
userService.add(user);
}
@Test
public void testAdd_old2() throws Exception {
System.out.println("當前執行方法 " + this.getClass().getSimpleName()+ ":" + new Exception().getStackTrace()[0].getMethodName());
BeanFactory factory = new ClassPathXmlApplicationContext();
UserService userService = new UserService();
UserDAO userDAO = (UserDAO) factory.getBean("u");
userService.setUserDAO(userDAO);
User user = new User();
userService.add(user);
}
@Test
public void testAddSpringMN() throws Exception {
System.out.println("當前執行方法 " + this.getClass().getSimpleName()+ ":" + new Exception().getStackTrace()[0].getMethodName());
BeanFactory factory = new ClassPathXmlApplicationContext();
System.out.println("/*------------------------------------------------------");
System.out.println(" 1、調用構造方法自動初始化 \n 2、jdom2讀取配置bean.xml,\n 3、通過讀取配置的bean.xml反射實例化讀取的配置文件中的類和service;\n factory=" + factory);
System.out.println("------------------------------------------------------*/");
UserService userService = (UserService) factory.getBean("userService");//該操作在Spring中通過注入方式DI實現 @Autowired private UserService userService; 當編譯生成class字節碼時spring掃描配置文件中設置的java包文件,讀取文件內容生成相關預加載xml,當項目啓動時進行實例化
System.out.println("/*------------------------------------------------------");
System.out.println("該操作在Spring中通過注入方式DI實現 @Autowired private UserService userService; \n1、當編譯生成class字節碼時spring掃描配置文件中設置的java包文件;\n2、讀取文件內容生成相關預加載xml;\n3、當項目啓動時進行實例化");
System.out.println("------------------------------------------------------*/");
User user = new User();
userService.add(user);
}
@Test
public void readXMLText() throws Exception {
System.out.println("當前執行方法 " + this.getClass().getSimpleName()+ ":" + new Exception().getStackTrace()[0].getMethodName());
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext();
classPathXmlApplicationContext.readXML();
}
}
/*---------------------------------------執行測試類結果-----------------------------------------*/
/*---------------------------------------執行測試類結果-----------------------------------------*/
/*---------------------------------------執行測試類結果-----------------------------------------*/
/*---------------------------------------執行測試類結果-----------------------------------------*/
"D:\Program Files\jdk1.6.0_43\bin\java" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA
....com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 com.spring.UserServiceTest
當前執行方法 UserServiceTest:testAdd_old1
調用DAO層 DB Save...
調用DAO層 DB Save...com.spring.model.User@f6a746
16164678 : 16164678 : {"id":0}
當前執行方法 UserServiceTest:testAdd_old2
jdom2 解析xml文件 :
外循環次數======3
id=== u
clazz=== com.spring.dao.impl.UserDAOImpl
id:clazz u:com.spring.dao.impl.UserDAOImpl
O=== com.spring.dao.impl.UserDAOImpl@fec107
T1null
T2[]
內循環次數======1
id=== userService
clazz=== com.spring.service.UserService
id:clazz userService:com.spring.service.UserService
O=== com.spring.service.UserService@1617189
T1[Element: <property/>]
T2[[Element: <property/>]]
內循環次數======2
beanObject====com.spring.dao.impl.UserDAOImpl@fec107
T4 method name=setUserDAO
獲取第一個類方法 method== public void com.spring.service.UserService.setUserDAO(com.spring.dao.UserDAO)
key = u, value = com.spring.dao.impl.UserDAOImpl@fec107
key = userService, value = com.spring.service.UserService@1617189
調用DAO層 DB Save...
調用DAO層 DB Save...com.spring.model.User@64f6cd
6616781 : 6616781 : {"id":0}
當前執行方法 UserServiceTest:readXMLText
jdom2 解析xml文件 :
外循環次數======3
id=== u
clazz=== com.spring.dao.impl.UserDAOImpl
id:clazz u:com.spring.dao.impl.UserDAOImpl
O=== com.spring.dao.impl.UserDAOImpl@872380
T1null
T2[]
內循環次數======1
id=== userService
clazz=== com.spring.service.UserService
id:clazz userService:com.spring.service.UserService
O=== com.spring.service.UserService@2bb514
T1[Element: <property/>]
T2[[Element: <property/>]]
內循環次數======2
beanObject====com.spring.dao.impl.UserDAOImpl@872380
T4 method name=setUserDAO
獲取第一個類方法 method== public void com.spring.service.UserService.setUserDAO(com.spring.dao.UserDAO)
開始遍歷第1節點======
屬性名是:id
屬性值是:u
屬性名是:class
屬性值是:com.spring.dao.impl.UserDAOImpl
結束遍歷第1節點======
開始遍歷第2節點======
屬性名是:id
屬性值是:userService
屬性名是:class
屬性值是:com.spring.service.UserService
結束遍歷第2節點======
如調試運行異常需將beans.xml複製到相關class 目錄下
當前執行方法 UserServiceTest:testAddSpringMN
jdom2 解析xml文件 :
外循環次數======3
id=== u
clazz=== com.spring.dao.impl.UserDAOImpl
id:clazz u:com.spring.dao.impl.UserDAOImpl
O=== com.spring.dao.impl.UserDAOImpl@16fa474
T1null
T2[]
內循環次數======1
id=== userService
clazz=== com.spring.service.UserService
id:clazz userService:com.spring.service.UserService
O=== com.spring.service.UserService@95c083
T1[Element: <property/>]
T2[[Element: <property/>]]
內循環次數======2
beanObject====com.spring.dao.impl.UserDAOImpl@16fa474
T4 method name=setUserDAO
獲取第一個類方法 method== public void com.spring.service.UserService.setUserDAO(com.spring.dao.UserDAO)
/*------------------------------------------------------
1、調用構造方法自動初始化
2、jdom2讀取配置bean.xml,
3、通過讀取配置的bean.xml反射實例化讀取的配置文件中的類和service;
factory=com.spring.ClassPathXmlApplicationContext@191d8c1
------------------------------------------------------*/
key = u, value = com.spring.dao.impl.UserDAOImpl@16fa474
key = userService, value = com.spring.service.UserService@95c083
/*------------------------------------------------------
該操作在Spring中通過注入方式DI實現 @Autowired private UserService userService;
1、當編譯生成class字節碼時spring掃描配置文件中設置的java包文件;
2、讀取文件內容生成相關預加載xml;
3、當項目啓動時進行實例化
------------------------------------------------------*/
調用DAO層 DB Save...
調用DAO層 DB Save...com.spring.model.User@2d9c06
2989062 : 2989062 : {"id":0}
Process finished with exit code 0