記事のディレクトリ
I.はじめに
春は2つの重要な機能、1つのAOP(アスペクト指向プログラミング)、ダイナミック・エージェント技術の主な用途を持っています
第二にIOC(制御の反転)技術。制御の反転が管理する春IOCコンテナに権利オブジェクトを作成され、開発者は、クラスの基礎となる様々な依存関係を考慮せずに関係を作成し、トップレベルのクラスを作成するに焦点を当てる必要がありますが、それらは作成するために、春IOCに引き渡されています。
技術は、IOC、IOCアナログ的使用セッター注入法の反射モード解析技術+ DOM4Jプロファイル+ xmlの簡単な操作で、本明細書で使用されます。
II。タイミング図
XML構造を解析するため々BeanUtilsを、そして豆グッドのマッピングとプロパティを構成するステップと、最後に、反射を得るための動作例をXmlApplicationContextによって達成されます
III。コードの実装
-
コードの全体的な構造
のコアコードはXmlApplicationContext及び々 BeanUtils、コードの200以上の行の合計に位置しています
-
豆袋
IOCによって必要な管理を格納するための豆の豆袋
/**
* @Auther: ARong
* @Date: 2020/2/13 12:51 下午
* @Description: Person类
*/
@Data
@ToString
public class Person {
private String name;
private Student student;
public Person() {
System.out.println(new Date() + ":Person类被创建");
}
}
/**
* @Auther: ARong
* @Date: 2020/2/13 12:55 下午
* @Description: Student类
*/
@Data
@ToString
public class Student {
private String name;
public Student() {
System.out.println(new Date() + ":Student类被创建");
}
}
- XMLパケット
applicationContext.xmlをXMLのパッケージの下に格納され、IOCコンテナすべてのクラスとレジスタに配置された場合
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean name="person" class="spring_demo.my_ioc.beans.Person" scope="prototype">
<properties>
<property name="name" value="ARong"/>
<property name="student" ref="student"/>
</properties>
</bean>
<bean name="student" class="spring_demo.my_ioc.beans.Student">
<properties>
<property name="name" value="XiaoMing"/>
</properties>
</bean>
</beans>
-
utilsパッケージ
のパッケージ定義utilsのプロパティと豆を、Beanクラス情報と属性情報を記述するために必要とされる、プログラムが反射簡単に作成されたインスタンスの豆を使用しています -
豆
/**
* @Auther: ARong
* @Date: 2020/2/13 1:00 下午
* @Description: 描述对象实例的抽象Bean
*/
@Data
@ToString
public class Bean {
private String name;// 类名
private String classpath;// 类全限定路径
private String scope = "singleton";// 默认单例
private List<Property> properties = new ArrayList<>();// 所含属性
}
- プロパティ
/**
* @Auther: ARong
* @Date: 2020/2/13 1:03 下午
* @Description: 描述类所含属性的抽象
*/
@Data
@ToString
public class Property {
private String name;// 属性名
private String value;// 属性值
private String ref;// 引用对象
}
解析された情報のXMLの構成を包装するための、さらに、々BeanUtils
- 々BeanUtils
/**
* @Auther: ARong
* @Date: 2020/2/13 1:09 下午
* @Description: Bean操作的工具类
*/
public class BeanUtils {
public static final BeanUtils DEFAULT = new BeanUtils();
private BeanUtils() {}
/*
* @Author ARong
* @Description 使用dom4j解析xml文件内容,封装对应的bean与相应属性
* @Date 2020/2/13 1:12 下午
* @Param [xmlPath]
* @return java.util.Map<java.lang.String,spring_demo.my_ioc.utils.Bean>
**/
public Map<String, Bean> getBeanConfig(String xmlPath) {
HashMap<String, Bean> map = new HashMap<>();
SAXReader saxReader = new SAXReader();
Document document = null;
try {
document = saxReader.read(xmlPath);
} catch (DocumentException e) {
e.printStackTrace();
}
Iterator<Element> beans = document.getRootElement().elementIterator();
while (beans.hasNext()) {
Element beanElement = beans.next();
// 封装bean
Bean bean = new Bean();
bean.setName(beanElement.attributeValue("name"));
bean.setClasspath(beanElement.attributeValue("class"));
String scope = beanElement.attributeValue("scope");
if (scope != null) {
bean.setScope(scope);
}
// 封装属性
ArrayList<Property> proList = new ArrayList<>();
Iterator<Element> properties = beanElement.element("properties").elementIterator();
while (properties.hasNext()) {
Element propertyElement = properties.next();
Property property = new Property();
property.setName(propertyElement.attributeValue("name"));
String value = propertyElement.attributeValue("value");
String ref = propertyElement.attributeValue("ref");
if (value != null) {
property.setValue(value);
}
if (ref != null) {
property.setRef(ref);
}
proList.add(property);
}
bean.setProperties(proList);
map.put(bean.getName(), bean);
// System.out.println(bean);
}
return map;
}
}
- コンテキストパケット
IOCコンテナとメソッドクラスによって得られるコンテキストパッケージは、例えば、XmlApplicationContextたBeanFactoryインタフェースと実装クラスを定義getBean - たBeanFactory
public interface BeanFactory {
/*
* @Author ARong
* @Description 根据name获取对象的实例
* @Date 2020/2/13 1:57 下午
* @Param [name]
* @return java.lang.Object
**/
Object getBean(String name);
}
- XmlApplicationContext
/**
* @Auther: ARong
* @Date: 2020/2/13 2:03 下午
* @Description:
*/
@Data
public class XmlApplicationContext implements BeanFactory {
private Map<String, Bean> beanMap;
private static final Map<String, Object> context = new HashMap<>();
private XmlApplicationContext() {
}
public XmlApplicationContext(String xmlPath) {
beanMap = BeanUtils.DEFAULT.getBeanConfig(xmlPath);
// 将单例对象先创建并放入context中
Set<Map.Entry<String, Bean>> entries = beanMap.entrySet();
for (Map.Entry<String, Bean> entry : entries) {
String key = entry.getKey();
Bean value = entry.getValue();
if ("singleton".equals(value.getScope())) {
context.put(key, createBean(value));
}
}
}
/*
* @Author ARong
* @Description 通过beanName获取Object
* @Date 2020/2/13 2:08 下午
* @Param [name]
* @return java.lang.Object
**/
@Override
public Object getBean(String name) {
Object instance = context.get(name);
if (instance == null) {
// 未创建的多例对象,每次都新创建
instance = createBean(beanMap.get(name));
}
return instance;
}
/*
* @Author ARong
* @Description 通过反射创建相应的对象
* @Date 2020/2/13 2:13 下午
* @Param [name, beanMap, context]
* @return java.lang.Object
**/
public Object createBean(Bean bean) {
// 获取类全限定名
String classpath = bean.getClasspath();
Class<?> beanClass = null;
try {
beanClass = Class.forName(classpath);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 创建class对象实例
Object beanInstance = null;
try {
beanInstance = beanClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
// 获得Bean的属性,将其注入
if(bean.getProperties() != null){
for(Property prop : bean.getProperties()){
// 获得要注入的元素名称
String proName = prop.getName();
// 根据属性名称获得对应属性的set方法
Method setMethod = getSetMethod(beanInstance, proName);
Object param = null;
if(prop.getValue() != null){
// value属性注入
param = prop.getValue();
}
if(prop.getRef() != null){
// bean引用注入
//要注入其他bean到当前bean中,先从容器中查找,当前要注入的bean是否已经创建并放入容器中
Object existBean = context.get(prop.getRef());
if(existBean == null){
// 容器中不存在要注入的bean,创建该bean
existBean = createBean(beanMap.get(prop.getRef()));
// 将创建好的单例bean放入容器中
if("singleton".equals(beanMap.get(prop.getRef()).getScope())) {
context.put(prop.getRef(), existBean);
}
}
param = existBean;
}
try {
// 调用set方法注入该属性
setMethod.invoke(beanInstance, param);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
return beanInstance;
}
/*
* @Author ARong
* @Description 通过反射获取到实例的变量setter方法
* @Date 2020/2/13 2:32 下午
* @Param [beanInstance, proName]
* @return java.lang.reflect.Method
**/
private Method getSetMethod(Object beanInstance, String proName) {
Class<?> beanClass = beanInstance.getClass();
Method setterMathod = null;
// 先获取方法参数类型
Class<?> type = null;
try {
type = beanClass.getDeclaredField(proName).getType();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
String begin = proName.substring(0, 1).toUpperCase();
String methodName = "set" + begin + proName.substring(1);
// 获取setter方法
try {
setterMathod = beanClass.getDeclaredMethod(methodName, type);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return setterMathod;
}
}
- テストパッケージ
の簡単なテストのためのIOC - TestIOC
/**
* @Auther: ARong
* @Date: 2020/2/13 1:24 下午
* @Description: 测试IOC容器
*/
public class TestIoC {
@Test
public void testIOC() {
// 1.初始化IOC容器
System.out.println("==========1.初始化IOC容器==========");
XmlApplicationContext context = new XmlApplicationContext("/Users/arong/MyFile/Project/Algorithm/src/main/java/spring_demo/my_ioc/xml/applicationContext.xml");
// 2.测试注入在Student中注入name属性
System.out.println("==========2.测试注入在Student中注入name属性==========");
testGetBean1(context);
// 3.测试在Person中注入student引用以及name属性
System.out.println("==========3.测试在Person中注入student引用以及name属性==========");
testGetBean2(context);
// 4.测试Person对象是否为多例、Student对象是否为单例
System.out.println("==========4.测试Person对象是否为多例、Student对象是否为单例==========");
testGetBean3(context);
}
private void testGetBean1(XmlApplicationContext context) {
Student student = (Student) context.getBean("student");
System.out.println(student+"\n");
}
private void testGetBean2(XmlApplicationContext context) {
Person person = (Person) context.getBean("person");
System.out.println(person+"\n");
}
private void testGetBean3(XmlApplicationContext context) {
Student student1 = (Student) context.getBean("student");
Student student2 = (Student) context.getBean("student");
System.out.println("student1 == student2:" + (student1 == student2));
Person person1 = (Person) context.getBean("person");
Person person2 = (Person) context.getBean("person");
System.out.println("person1 == person2:"+(person1 == person2));
}
出力ディスプレイ、IOC基本機能が正常で、コードの200行は、IOCのコアコードです。ライフサイクルを管理する方法の豆具体的な例?そして、さらにどのようにメソッドをスキャン注釈を設定する洗練された〜