在演示之前,首先得要一个IDEA,不过具体的安装这里就不再赘述了,网络上方法很多。
1.操作演示
2.原理讲解
one 操作演示部分
1.在idea中新建项目,具体操作是左上角File->New->Project
在出来的界面在最左侧找Maven项目,然后上方的jdk版本一定要跟自己本地安装的jdk版本匹配,最后才是点击next下一步
然后是填写组名和项目
next以后会让你选择存储路径,这个可以自己修改,我这边就先默认了
2.建立完以后进行pom.xml文件配置,这个文件是在你创建完成后自动就会出现的。
然后是追加依赖:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.13.RELEASE</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
当然这些依赖也是需要下载下来的。
以及下载一些必要的库资源
你会看到控制台上的报错,我网上搜索了一下说这是本地meaven库不匹配导致的,但实际上我看了一下setting里的meaven设置是没有问题的,而且等到第二天我重新打开的时候报错也没有了。这里估计有一个小坑,但今天并没有找到什么合适的办法能有效的解决,所以就暂且搁置先进行我们的演示部分。
3.然后我们在src->main->java里创建一个Package包
然后在这个包里我建立了三个java文件:MessageService,MessagePrinter,Application
MessageService.java
package project;
import org.springframework.stereotype.Component;
@Component
public class MessageService {
public MessageService() {
super();
System.out.println("MessageService");
}
/**
* 执行打印功能
* @return 返回要打印的字符串
* */
public String getMessage(){
return "HELLO";
}
}
MessagePrinter.java
package project;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MessagePrinter {
public MessagePrinter() {
super();
System.out.println("Messageprinter");
}
//建立和MessageService的关联
private MessageService service;
@Autowired
public void setService(MessageService service){
this.service=service;
}
public void printMessage(){
System.out.println(this.service.getMessage());
}
}
Application.java
package project;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan
public class Application {
public static void main(String[] args) {
System.out.println("application spring");
//初始化spring容器
ApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
//从容器中获取Messageprinter对象
MessagePrinter printer = context.getBean(MessagePrinter.class);
printer.printMessage();
}
}
然后我们右键Run运行Application.java,结果如下
two 原理讲解
然后,这样一个简单的java程序能说明什么呢?
说明比起传统的java程序,这样的写法更简洁。
为什么简洁?为什么Application里不需要new前两个类的对象?
而这一切的省略和一切的简洁都要归功与spring。
项目的最开始,我们在xml文件里导入了许多依赖(dependency)
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.13.RELEASE</version>
</dependency>
</dependencies>
依赖是什么?依赖是汽车的汽油,是中性笔的笔芯,是spring在本地进行操作的凭证,根据亚里士多德的四因说(形式因,目的因,质料因,动力因)来判断,这里的依赖就是spring的质料。古人云:“兵不利,战不善。”如果战本身代指的是spring,那这里的依赖注入就是指的利兵之道,淬刃之法。
然后我们解决完了依赖开始写程序,程序的开头注明了我们的package,往下是import导入包,当然,前提是我们的依赖已经处理好了,否则是没办法进行包导入的。
然后我们琢磨代码,发现有一些@Component之类的东西,这些东西有点像注释,但本身其实是注解,而在介绍注解之前,我们自然要先引入一个spring的核心概念IOC(inversion of control),翻译过来是反转控制。
反转啥?怎么反转?控制怎么反转?
因此,实际上这个反转控制并不容易理解,所以这里我把它颠倒过来,说反转控制其实是控制反转,更确切的说,是控制的反转。
控制啥?怎么控制?控制怎么反转?
控制,是指的控制权,谁的控制权?代码的控制权?谁有控制权?写程序的人有控制权,哪怕是粘贴复制,写代码这一步骤也是需要人来帮助完成的。在写一般的java程序的时候,像是对象实例化这一步骤就是需要我们去手动敲的。比如我们我们一个类叫 Message,我们就得写一个Message message = new Message,所以这个写实例化的控制权就是在程序员手里的。
但实际上我们的Application.java代码里根本没有写什么MessagePrinter message = new MessagePrinter,虽然我们也在new,但并不是new的具体的对象,那这一步是被省略了吗?
不可能,如果省略了是没办法执行的,所以这一步的的确确是执行的,只不过我们看不见, 那既然不是我们执行的,那就是其他的什么东西来执行的,而这个东西就是spring。
我觉得实例化这个步骤不难,而且我也不想写,所以我告诉spring去替我干了。
所以,这一次实例化的控制权跑到spring手里去了,控制权从原本在程序员手里又回流进了程序里,这不就是说控制权颠倒了吗,颠倒不就是反转了吗。
回到四因说,质料,目的,形式,动力。
质料是java的环境依赖,我写程序的目的是为了让它打印一个hello,程序完成的形式是通过spring托管以及人为的运行来实现,那还差最后一个:动力。
那是否我们在前面提到过所谓的注解?
spring虽然高效,但是它傻啊,你不告诉它去做什么,它是不会自己琢磨着该去干什么,它的轮子需要一个外力来作为动力启动。所以,我们要额外的对他下一个口令,这个专属于spring的口令,叫做注解。
比如注解@Component,component本身是部件的意思,我给程序的脑袋上安一个插件,贴一个标签,告诉spring它实例化的工作该你来干了,然后我们在主程序里写一个@ComponentScan,就是告诉spring这个程序是负责人,它负责管理所有脑袋有component的部件,等他想用这些部件的时候spring 需要把一切工作做好,而ComponentScan只需要坐享其成就可以了。
而其他一些的带有@开头的注解,那便是一些具备其他功能的指令了,这里就不再一一介绍了。
而程序中其他有跟寻常java程序不一样的地方就是
//初始化spring容器
ApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
//从容器中获取Messageprinter对象
MessagePrinter printer = context.getBean(MessagePrinter.class);
这一部分了,而这些已经在注释里介绍了,是一些spring专属的方法,毕竟,spring虽然高效,但你在使用前最起码要给它开机(初始化spring容器)一下吧,开完机了还得告诉它跟谁去干活(从容器中获取Messageprinter对象)吧,所以才会有这些步骤的出现。