Marco's Java【Spring入门(二) 之 控制反转IoC】 - Go语言中文社区

Marco's Java【Spring入门(二) 之 控制反转IoC】


什么是IoC

IoC是的全称是Invertion of Control,也就是控制反转,相信大家听到这个名词仍然会很懵逼。
那么我们先从字面上分析。控制的是什么?反转什么?
大家应该知道,我们写代码经常重复做的一件事情是啥? 创建对象对吧?
那么不管是通过new对象也好,反射创建对象也罢,对白了,都是要我们手动的去写代码创建,但是现在使用了Spring框架,我们就可以当"甩手掌柜"了。为什么这么说呢?
因为Spring的核心功能之一IoC可以帮我们new对象,管理对象,可以说它就像智能机器人,原先需要我们自己烧菜做饭,那你交给它,就可以做出美味佳肴,直接吃就得了。

那么现在我们就可以回答上面问题了
控制: 控制的是类的对象
反转: 反转角色,将new对象的角色交给了Spring

怎么做最大的好处就是解除了对象管理和程序员的耦合关系,好处的话相信大家大概可以感受的到了吧
好比说我们使用MyBatis,最少得有三步吧。

InputStream is = Resource.getResourceAsStream("mybatis.xml");//获取流对象
SqlSessionFactor factory = new SqlSessionFactorBuilder().build(is);//获取Session工厂对象
SqlSession session = factory.openSession();//获取Session对象

其实大家应该可以感觉的到,这些步骤都是重复不变的,JDBC创建Connection对象也是一样,很麻烦对吧,所以在没有框架的时候,我个人都喜欢把这些操作给封装起来,然后一键get对象。。所以说懒人的想象是无穷的,我觉得Rod Johnson应该是个"懒人",否则不可能开发出来这么便利省事的东西。

到这里相信大家对控制反转应该有自己的理解了对吧。使用IoC可以大大的提高开发的效率,节省了一些不必要的时间。

Spring的基本环境搭建

1)一成不变,先导jar包
首先最基本的四个包需要导入:Beans,Core,Context,SpEL,另外我这边还导入了一个commons日志包,这个也非常重要,用于记录我们程序运行产生的日志。
在这里插入图片描述
2)配置运行文件
接下来在src路径下新建一个applicationContext.xml(名字任意取,一般取这个名称),因为我们Spring最大的容器是ApplicationContext,且最终的配置信息都会存储在ApplicationContext容器中

之前我们有提到过schema大家是否还有印象?我们再来回顾一下
schema:存放配置文件,文件的扩展名是.xsd,可以把它理解成DTD(xml的语法检查器)的升级版,扩展性更强
我们每次引入的xsd文件实则是一个namespace(xmlns),那什么是xmlns呢

<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>

大家可以看到上面的配置文件头部,是不是和xml文件的头部有点像,但是在xml中DTD是单独的放在最上面的头部,下面才是根节点,而大家可以看到这里的xmlns是一个属性,在他的最下面就是xsd文件路径
http://www.springframework.org/schema/beans/spring-beans.xsd
默认是在网络上加载的,加载成功之后,我们用ctrl+/快捷键就可以发现出来很多提醒性标签了。那么怎么理解他的扩展性呢?我们先去他的主页面搜索xmlns:aop搜到下面的配置文件
在这里插入图片描述
然后将xmlns:aop="http://www.springframework.org/schema/aop"http://www.springframework.org/schema/aop/spring-aop.xsd复制到我们的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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>

当我们发现使用ctrl+/快捷键能出来以下标签,证明配置文件就已经配好了
在这里插入图片描述
如果使用Maven,那么直接在pom.xml中做如下配置即可

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>4.1.6.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>4.1.6.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>4.1.6.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-expression</artifactId>
  <version>4.1.6.RELEASE</version>
</dependency>  

3)配置bean
接下来我们在applicationContext.xml中的beans中再加上

<!-- id: 获取对象的标识 
     class: 对象的类  -->
<bean id="user" class="com.marco.pojo.User"></bean>

4)新建JavaBean
配置好后,我们就创建一个User类来测试一下啦,设定user中的属性如下,get和set方法我这里就不写啦

private int id;
private String userName;
private String password;
private String realName;

5)通过ApplicationContext获取bean对象
新建一个Test测试类

public class Test {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");//类路径
		User user = ac.getBean("user", User.class);
		System.out.println(user);
	}
}

运行成功后结果如下所示,需要注意的是,我们的对象是在配置文件加载的完成就创建的,且默认是通过无参构造创建对象的
在这里插入图片描述
另外通过以下方法,我们可以获取容器中所有的bean id

String[] names = ac.getBeanDefinitionNames();
for (String name : names) {
	System.out.println(name);
}

Spring创建对象的方式

构造方法创建

无参构造
之前我们提到了Spring创建对象默认都是通过反射使用无参构造创建的,我们可以测试一下
首先,我们在User的无参构造方法中添加打印语句

public User() {
	System.out.println("无参构造");
}

我们发现"无参构造"被打印了,这是否就证明了Spring创建对象默认都是使用的无参构造呢?
在这里插入图片描述

有参构造
使用有参构造需要明确配置才能创建,具体配置如下
在这里插入图片描述
接下来我们在有参构造器中加上一句话测试一下

public User(int id, String userName, String password, String realName) {
		System.out.println("有参构造");
		this.id = id;
		this.userName = userName;
		this.password = password;
		this.realName = realName;
}

结果发现"有参构造"被打印了
在这里插入图片描述
需要注意的是如果是通过index的方式指定value,假设我们有多个构造方法,但是参数的顺序不一样,那么走的是哪个构造呢?一般默认是走从下往上的第一个构造方法,那该怎么控制具体走哪一个构造方法呢?
这个时候我们就可以使用name结合type来赋值了,这样我们调用构造方法的参数顺序肯定是
public User(int id, String userName, String password, String realName)
在这里插入图片描述

实例工厂创建

工厂顾名思义就是生产产品的,但是这里我们的工厂就是创建对象的,工厂创建对象的好处就是我只用指定要什么对象可以生产不同类型的对象。我们先并创建两个不同的用户角色Sales和Operation,再建一个User工厂。

public class UserFactory {
	public User createUser(String role) {
		switch (role) {
		case "sales":
			return new Sales();
		case "operation":
			return new Operation();
		default:
			return null;
		}
	}
}

这个时候我们需要先new一个UserFactory对象再调用createUser方法,获取到不同的对象
那么在Spring中我们也可以通过配置来用工厂获取到实例对象,首先还是新建一个工厂类

public class UserFactory {
	public User newInstance() {
		return new User();
	}
}

然后在xml中配置

<bean id="userFactory" class="com.marco.pojo.UserFactory"></bean>
<bean id="user" factory-bean="userFactory" factory-method="newInstance"></bean>

运行结果和无参构造运行的结果相同

静态工厂创建

静态工厂无非就是工厂的生产对象的方法必须是静态的,需要用static修饰的,因此,我们newInstance()方法需要修改为

public class UserFactory {
	public static User newInstance() {
		return new User();
	}
}

然后在xml中配置好后,运行的结果和实例工厂是一样的

<bean id="user" class="com.marco.pojo.UserFactory" factory-method="newInstance"></bean>

在这里插入图片描述

实例工厂和静态工厂的区别就是,实例工厂需要先获取工厂对象,然后通过工厂对象再创建对象,而静态工厂则不需要工厂对象并快速的创建对象

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_44698119/article/details/94356727
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢