通俗谈 Spring IOC ,自己动手实现简版IOC
2018-01-18 22:05
239 查看
因为要面试JAVA岗工程师,对Spring 的IOC 原理还是必须明确的,所以就花了点时间自己认真摸索了下。
Spring IOC (Inversion Of Control),控制反转。想起初学IOC的时候,一头雾水,什么是IOC?
通俗的讲:就是本来应该有程序员自己new 一个对象,但是现在你不需要new 了,而是框架帮你new 了对象。这种对象的创建(其他管理)权利的给了框架,就被称为IOC(控制反转)。看到这里大家应该清楚了很多。
下面我通过自己代码实现了Spring IOC 中我们常用的@Autowrid 和@Service(通过标签自动注入对象),和IOC中的BeanFactory 对配置文件中的bean进行管理。
一.通过标签进行自动注入对象(一般是在service 中自动诸如Dao 对象)。
代码如下:
1.MyService标签类(模仿@Service):
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
@Target({ElementType.TYPE})//类
@Retention(RetentionPolicy.RUNTIME)//运行时
public @interface MyService {
}
2.MyAutoWrid 标签类(模仿@Autowrid):
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
@Target(ElementType.FIELD)//方法
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAutoWrid {
}
3.service 接口:
public interface PriceService {
void show_price();
}
4.service接口实现(主角1 打上了我们自定义的标签,自动注入一个对象):
@MyService
public class PriceServiceImpl implements PriceService {
@MyAutoWrid
Price_getter price_getter; // 自动注入一个对象
public void show_price() {
price_getter.show_price();
}
}5.Dao类(假装从数据库获取了数据):
public class Price_getter {
//假装从数据库读取数据
void show_price(){
System.out.println("你的价格是5元!!!!");
}
}
6.注入对象的工具类:
import java.lang.reflect.Field;
public class Fill_varlible_Tool {
//注入Dao对象后的service
public Object finsh_object;
//对标签进行解析,并且通过反射实现对象,并将其赋值给service
public void fill_Object(Object target) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//获取需要自动注入对象的类
Class<?> fatherclazz=target.getClass();
//判断该类是否有Myservice标签
if(fatherclazz.isAnnotationPresent(MyService.class)){
//获取该类的所有属性
Field[] fields=fatherclazz.getDeclaredFields();
for(Field item:fields){
//判断属性是否带有标签 MyAutoWrid
if(item.isAnnotationPresent(MyAutoWrid.class)){
//反射获取该类,实例化对象并且赋值给对应的属性
Class<?> subclazz=Class.forName(item.getType().getName(),false,Thread.currentThread().getContextClassLoader());
item.set(target,subclazz.newInstance());
finsh_object=target;
}
}
}
}
//返回注入后的对象
public Object getFinsh_object() {
return finsh_object;
}
}
7.初始化容器类:
//初始化容器类
public class InitContainer {
//模拟web程序启动的时候,对传入的service 进行注入对象
public Object init(Object object) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
Fill_varlible_Tool tool=new Fill_varlible_Tool();
tool.fill_Object(object);
return tool.getFinsh_object();
}
}
8.测试类(模拟应用启动):
public class MainTest {
public static void main(String[] args) throws IllegalAccessException, ClassNotFoundException, InstantiationException {
InitContainer container=new InitContainer();
//本应该扫描获取有标记 MyService的class 并且new 出他们的对象
PriceServiceImpl priceService=new PriceServiceImpl();
//通过容器初始化对他们的Dao 属性进行自动赋值
priceService=(PriceServiceImpl) container.init(priceService);
priceService.show_price();
}
}
9.运行结果:
你的价格是5元!!!!
Process finished with exit code 0
二.通过配置文件,使用BeanFactory 管理bean的IOC。
1.MyBeanFactory类(模拟BeanFactory):
public interface MyBeanFactory {
Object getbean(String id);
}
2.实现MyBeanFactory:
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.HashMap;
import java.util.List;
public class MyBeanFactoryImpl implements MyBeanFactory {
private HashMap<String, Object> mymap = new HashMap<String, Object>();
public MyBeanFactoryImpl(String filename) throws DocumentException, ClassNotFoundException, IllegalAccessException, InstantiationException {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(filename));
List<Element> elements = document.selectNodes("/beans/bean");
for (Element item : elements) {
String id = item.attributeValue("id");
String class_val = item.attributeValue("class");
Object object=Class.forName(class_val).newInstance();
mymap.put(id,object);
}
}
public Object getbean(String id) {
return mymap.get(id);
}
}
3.一般接口 Skill:
public interface Skill {
void show_myskill();
}
4.实现Skill接口的Programmer类:
public class Programmer implements Skill {
public void show_myskill() {
System.out.println("编程写软件");
}
}5.实现Skill接口的Doctor类:
public class Doctor implements Skill{
public void show_myskill() {
System.out.println("看病救人");
}
}
6.定义bean的配置文件 applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="d" class="SpringIoc_xml.Doctor"></bean>
<bean id="p" class="SpringIoc_xml.Programmer"></bean>
</beans>
7.测试类Test(模拟应用启动):
import org.dom4j.DocumentException;
public class Test_XMl {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, DocumentException, IllegalAccessException {
MyBeanFactory myBeanFactory=new MyBeanFactoryImpl("C:\\Users\\Administrator\\Desktop\\applicationContext.xml");
Skill skill= (Skill) myBeanFactory.getbean("d");
skill.show_myskill();
Skill skill2= (Skill) myBeanFactory.getbean("p");
skill2.show_myskill();
}
}8.运行结果:
看病救人
编程写软件
Process finished with exit code 0
这些是我对Spring 的IOC的理解和简单实现,如果有不对的地方,恳请批评指正。
Spring IOC (Inversion Of Control),控制反转。想起初学IOC的时候,一头雾水,什么是IOC?
通俗的讲:就是本来应该有程序员自己new 一个对象,但是现在你不需要new 了,而是框架帮你new 了对象。这种对象的创建(其他管理)权利的给了框架,就被称为IOC(控制反转)。看到这里大家应该清楚了很多。
下面我通过自己代码实现了Spring IOC 中我们常用的@Autowrid 和@Service(通过标签自动注入对象),和IOC中的BeanFactory 对配置文件中的bean进行管理。
一.通过标签进行自动注入对象(一般是在service 中自动诸如Dao 对象)。
代码如下:
1.MyService标签类(模仿@Service):
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
@Target({ElementType.TYPE})//类
@Retention(RetentionPolicy.RUNTIME)//运行时
public @interface MyService {
}
2.MyAutoWrid 标签类(模仿@Autowrid):
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
@Target(ElementType.FIELD)//方法
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAutoWrid {
}
3.service 接口:
public interface PriceService {
void show_price();
}
4.service接口实现(主角1 打上了我们自定义的标签,自动注入一个对象):
@MyService
public class PriceServiceImpl implements PriceService {
@MyAutoWrid
Price_getter price_getter; // 自动注入一个对象
public void show_price() {
price_getter.show_price();
}
}5.Dao类(假装从数据库获取了数据):
public class Price_getter {
//假装从数据库读取数据
void show_price(){
System.out.println("你的价格是5元!!!!");
}
}
6.注入对象的工具类:
import java.lang.reflect.Field;
public class Fill_varlible_Tool {
//注入Dao对象后的service
public Object finsh_object;
//对标签进行解析,并且通过反射实现对象,并将其赋值给service
public void fill_Object(Object target) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//获取需要自动注入对象的类
Class<?> fatherclazz=target.getClass();
//判断该类是否有Myservice标签
if(fatherclazz.isAnnotationPresent(MyService.class)){
//获取该类的所有属性
Field[] fields=fatherclazz.getDeclaredFields();
for(Field item:fields){
//判断属性是否带有标签 MyAutoWrid
if(item.isAnnotationPresent(MyAutoWrid.class)){
//反射获取该类,实例化对象并且赋值给对应的属性
Class<?> subclazz=Class.forName(item.getType().getName(),false,Thread.currentThread().getContextClassLoader());
item.set(target,subclazz.newInstance());
finsh_object=target;
}
}
}
}
//返回注入后的对象
public Object getFinsh_object() {
return finsh_object;
}
}
7.初始化容器类:
//初始化容器类
public class InitContainer {
//模拟web程序启动的时候,对传入的service 进行注入对象
public Object init(Object object) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
Fill_varlible_Tool tool=new Fill_varlible_Tool();
tool.fill_Object(object);
return tool.getFinsh_object();
}
}
8.测试类(模拟应用启动):
public class MainTest {
public static void main(String[] args) throws IllegalAccessException, ClassNotFoundException, InstantiationException {
InitContainer container=new InitContainer();
//本应该扫描获取有标记 MyService的class 并且new 出他们的对象
PriceServiceImpl priceService=new PriceServiceImpl();
//通过容器初始化对他们的Dao 属性进行自动赋值
priceService=(PriceServiceImpl) container.init(priceService);
priceService.show_price();
}
}
9.运行结果:
你的价格是5元!!!!
Process finished with exit code 0
二.通过配置文件,使用BeanFactory 管理bean的IOC。
1.MyBeanFactory类(模拟BeanFactory):
public interface MyBeanFactory {
Object getbean(String id);
}
2.实现MyBeanFactory:
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.HashMap;
import java.util.List;
public class MyBeanFactoryImpl implements MyBeanFactory {
private HashMap<String, Object> mymap = new HashMap<String, Object>();
public MyBeanFactoryImpl(String filename) throws DocumentException, ClassNotFoundException, IllegalAccessException, InstantiationException {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(filename));
List<Element> elements = document.selectNodes("/beans/bean");
for (Element item : elements) {
String id = item.attributeValue("id");
String class_val = item.attributeValue("class");
Object object=Class.forName(class_val).newInstance();
mymap.put(id,object);
}
}
public Object getbean(String id) {
return mymap.get(id);
}
}
3.一般接口 Skill:
public interface Skill {
void show_myskill();
}
4.实现Skill接口的Programmer类:
public class Programmer implements Skill {
public void show_myskill() {
System.out.println("编程写软件");
}
}5.实现Skill接口的Doctor类:
public class Doctor implements Skill{
public void show_myskill() {
System.out.println("看病救人");
}
}
6.定义bean的配置文件 applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="d" class="SpringIoc_xml.Doctor"></bean>
<bean id="p" class="SpringIoc_xml.Programmer"></bean>
</beans>
7.测试类Test(模拟应用启动):
import org.dom4j.DocumentException;
public class Test_XMl {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, DocumentException, IllegalAccessException {
MyBeanFactory myBeanFactory=new MyBeanFactoryImpl("C:\\Users\\Administrator\\Desktop\\applicationContext.xml");
Skill skill= (Skill) myBeanFactory.getbean("d");
skill.show_myskill();
Skill skill2= (Skill) myBeanFactory.getbean("p");
skill2.show_myskill();
}
}8.运行结果:
看病救人
编程写软件
Process finished with exit code 0
这些是我对Spring 的IOC的理解和简单实现,如果有不对的地方,恳请批评指正。
相关文章推荐
- 自己动手写一个web框架(一):实现IOC与MVC
- 自己动手实现一个简单的 IOC
- 自己动手实现Spring IoC框架
- 自己动手实现Spring IoC框架
- 自己动手实现SpringIoC
- 自己动手实现Spring IoC框架
- 自己实现Spring IoC容器(四)IoC容器的Bug
- 自己实现Spring IoC容器(三)完成IoC容器
- [置顶] 关于JAVA动态加载类[简单IOC的实现] -- vb2005xu自己动手
- spring 之 自己动手实现IOC
- 自己动手实现spring ioc
- 自己动手实现一个简单的 IOC
- 自己动手实现HTTP协议
- 练习:自己动手实现一个轻量级的信号量(一)
- 如何自己动手实现 KVO(转)
- 自己动手实现 lucene 搜索代码高亮显示
- 自己动手实现简易的div可编辑富文本框及按下tab键后增加4个空格功能
- 自己动手实现光栅化直线生成算法
- 自己动手开发网络服务器(二):实现WSGI服务
- 自己动手实现简单权限控制_0