本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
1 IOC介绍
Spring是一个开源的、松耦合的、分层的、可配置的、一站式的企业级Java开发框架,核心是IOC和AOP。
其中本文要介绍的就是IOC的一种实现方法依赖查找(DL)。
现在先介绍一下IOC:
IOC(控制反转)不是一种技术,而是一种思想。在以往的编程过程中,都是我们主动的在类的内部创建需要的对象,这种对象就是我们所看到的依赖对象。这种方法导致的一个问题就是,类和类之间的耦合度超高,不便于业务的扩展和修改,以及及其难以测试。
而IOC的思想就是,将原来我们手动new bean的权力交出去,交给Spring去做,而放置和管理这些bean的就是IOC容器。就像在没有餐馆以前,你想要吃什么菜,你要自己根据食谱(类Class),来自己制作一道菜(对象Bean)。而现在你想吃什么就去点菜,厨子(Spring)会把菜给你做好,并送到你的餐桌上。
2 准备工作
首先要创建一个Maven项目,这里就不过多赘述,网上有很好的教学文章或视频。
2.1 引入依赖
这里我们主要体验一下几种使用xml文件来体验一把依赖查找,就只要在pom.xml文件中引入一个依赖spring-context
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
2.2 创建配置文件
可以理解成请一个厨子,里面装的都是他会做的菜品。
创建一个xml文件
初始化配置(新来的厨子啥也不会):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
2.3 创建一些类
搞几个菜谱,这里我们创建了麻婆豆腐和北京烤鸭(中国菜的名字真的好长)
//北京烤鸭
public class BeijingRoastDuck {
}
//麻婆豆腐
public class MapoTofu {
}
2.4 创建启动类
这里我们创建一个点菜通过名字的启动类,然后这里使用main函数
public class OrderByNameApplication {
public static void main(String[] args) {
}
}
2.5 在配置文件进行声明
就是给厨子菜谱,在配置文件给这些菜声明一下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="BeijingRoastDuck" class="com.shea.restaurant.bean.BeijingRoastDuck"></bean>
<bean id="MapoTofu" class="com.shea.restaurant.bean.MapoTofu"></bean>
</beans>
餐馆一切都准备好了,接下来就是点菜了。
3 依赖查找的方式
可以理解成为,你去餐厅点菜,使用的是什么方式。
3.1 通过名字查找
通过菜名点菜。主要的方法getBean(String s)
你去到餐厅,开始点菜:
你:“欸,我想吃这个北京烤鸭,你这有不?”
厨子:“我看看啊!欸!有!”
那这个过程就是:
public class OrderByNameApplication {
public static void main(String[] args) {
//创建IOC容器 点菜的时候把厨子叫过来
BeanFactory factory = new ClassPathXmlApplicationContext("cook.xml");
//查找依赖 你和厨子点菜 厨子想一下会不会
BeijingRoastDuck beijingRoastDuck = (BeijingRoastDuck) factory.getBean("BeijingRoastDuck");
//这里我们就看看厨子的菜谱没有没找对(验证一下)
System.out.println(beijingRoastDuck);
}
}
打印的内容:
这个过程就是通过我们配置文件的id进行依赖查找,查找到依赖对象所在的类
3.2 通过类查找
通过食谱点菜,主要的方法getBean(Object object)
这次你去餐馆点菜,你有一个菜谱,但是不知道菜名,你就给厨子看:
你:“哥,我这有个菜谱,你看你会这个菜不?”
厨子:“我瞅瞅啊,欸!这个我会呀!给你做哈!”
过程如下:
public class OrderByTypeApplication {
public static void main(String[] args) {
//创建IOC容器 点菜的时候把厨子叫过来
BeanFactory factory = new ClassPathXmlApplicationContext("cook.xml");
//查找依赖 你不知道菜名,但是知道菜谱,你给厨子看,厨子看看自己会不会
MapoTofu mapoTofu = factory.getBean(MapoTofu.class);
//这里看看厨子会不会这个菜谱
System.out.println(mapoTofu);
}
}
打印内容:
这个方法就不需要进行强制类型转换了,都把类传进去了
3.3 取出所有类
通过菜单点菜,主要方法getBeansOfType(Object object)
这天你又去吃饭,但是你每啥头绪,然后你就想看看这厨子都会哪些菜
你:“今天不知道吃啥,可以看看你的菜谱吗?”
厨子:”没问题!“
过程如下:
这个时候我们就不能用BeanFactory我们要改用ApplicationContext,当然上面的BeanFactory是可以换成ApplicationContext的,两者的关系就是ApplicationContext是BeanFactory的子接口,同时官方也建议都使用ApplicationContext,因为它的功能更加丰富,性能更加优秀。
在进行这一步的操作前,我们先定义一个接口Food
public interface Food {
}
然后将我们的菜类全部实现这个接口,目录结构如下:
记得修改配置文件中的bean目录
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="BeijingRoastDuck" class="com.shea.restaurant.bean.impl.BeijingRoastDuck"></bean>
<bean id="MapoTofu" class="com.shea.restaurant.bean.impl.MapoTofu"></bean>
</beans>
启动类:
public class OrderOfTypeApplication {
public static void main(String[] args) {
//创建IOC容器 点菜的时候把厨子叫过来
ApplicationContext factory = new ClassPathXmlApplicationContext("cook.xml");
//查找依赖 你想看看厨子都会做什么菜
Map<String, Food> beans = factory.getBeansOfType(Food.class);
//厨子会做的菜和菜谱
beans.forEach((beanName, bean) -> {
System.out.println(beanName + " : " + bean.toString());
});
}
}
打印内容:
3.4 通过注解查找
通过菜的类别点菜,主要方法getBeansWithAnnotation(Object object)
你今天特别想吃北京菜,于是你去餐馆问厨子:
你:”你会做啥北京菜啊?“
厨子:“我给你看看”
我们先创建一个注释,叫BeijingFood
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface BeijingFood {
}
然后在北京烤鸭上面写这个注释
@BeijingFood
public class BeijingRoastDuck implements Food {
}
启动类:
public class OrderByAnnotationApplication {
public static void main(String[] args) {
//创建IOC容器 点菜的时候把厨子叫过来
ApplicationContext factory = new ClassPathXmlApplicationContext("cook.xml");
//查找依赖 你想看看厨子都会做什么北京菜
Map<String, Object> beans = factory.getBeansWithAnnotation(BeijingFood.class);
//厨子会做的菜和菜谱
beans.forEach((beanName, bean) -> {
System.out.println(beanName + " : " + bean.toString());
});
}
}
打印内容:
