[关闭]
@artman328 2017-09-19T14:23:02.000000Z 字数 9111 阅读 1225

Spring框架的核心功能

Spring Java Framework


一、Spring 框架的核心功能

1. 依赖注入(Dependency Injection)

2. 切向编程(AOP - Aspect-Oriented Programming)

二、依赖注入

1. 基本含义

在面向对象的编程世界里,一切事物都是类。各种类的对象相互交互完成业务过程。一个对象往往需要调用其它类的对象的方法来完成一些工作,通常,这样的对象需要自己创建这些其它类的对象来供自己使用。这会导致此对象的职责过重(需要自己管理其它类的对象),同时,会把自己与这些其它类紧紧联系在一起。

新的思路是:由一个容器类对象来管理所有类的对象,当一个对象需要一个其它类的对象来完成工作时,这个“其它类的对象”会被容器“注入”到此对象,此对象不必要自己创建这个“其它类的对象”。所有类的对象的生命周期,都由这个容器类来进行统一管理。

2. 举例

有一个业务类 DataService 用于提供数据服务,我们可提供数据给它进行处理,如:整理数据、输出数据等。

对于“输出数据”,我们希望可以根据需求输出到任意设备,如:磁盘、打印机等。因此,我们有两个类,DiskWriter 和 PrinterWriter,分别负责输出数据到磁盘和打印机。

因此,当需要输出数据时,DataService 类的对象要自己创建一个用于“输出数据”的对象(可以是 DiskWriter 或 PrinterWriter 的对象,这需要根据需求来决定),然后通过这个对象把数据输出到指定的设备。

(1)原始方法

Created with Raphaël 2.1.2原始方法过程AppAppdataService:DataServicedataService:DataServicediskWriter:DiskWriterdiskWriter:DiskWriter(创建)(创建)write()write()

我们先写 DiskWriter 类

  1. package org.artmansoft.demo;
  2. public class DiskWriter {
  3. public void write(String data) {
  4. //这里是实现写入磁盘的代码,为简便起见,略过
  5. System.out.println("已经将数据: " + data + " 写入磁盘!");
  6. }
  7. }

然后是 PrinterWriter 类:

  1. package org.artmansoft.demo;
  2. public class PrinterWriter {
  3. public void write(String data) {
  4. //这里是实现写入打印机的代码,为简便起见,略过
  5. System.out.println("已经将数据: " + data + " 写入打印机!");
  6. }
  7. }

接着是 DataServer 类:

  1. package org.artmansoft.demo;
  2. public class DataServer {
  3. private String data;
  4. private DiskWriter diskWriter; //这里直接指明了 DiskWriter 类以便写入磁盘,如果以后要写入其它设备如打印机,需要改动到其它类
  5. public void setData(String data) {
  6. this.data = data;
  7. }
  8. public void write() {
  9. if(this.writer == null){
  10. this.writer = new DiskWriter(); // 这里需要 new 一个 DiskWriter 对象
  11. }
  12. this.diskWriter.write();
  13. }
  14. }

最后是主程序类 App.java:

  1. package org.artmansoft.demo;
  2. public class App {
  3. private static DataService dataService;
  4. public static void main(String[] args) {
  5. dataService = new DataService(); //主程序需要 new 一个数据服务对象
  6. dataService.setData("77778888");
  7. dataService.write(); // 已经将数据: 77778888 写入磁盘!
  8. }
  9. }

(2)使用接口

Created with Raphaël 2.1.2使用接口过程AppAppdataService:DataServicedataService:DataServicediskWriter:IWriterdiskWriter:IWriter(创建)(创建)write()write()

我们先写一个接口:

  1. package org.artmansoft.demo;
  2. public interface IWriter {
  3. public void write(String data);
  4. }

DiskWriter 类

  1. package org.artmansoft.demo;
  2. public class DiskWriter implements IWriter {
  3. public void write(String data) {
  4. //这里是实现写入磁盘的代码,为简便起见,略过
  5. System.out.println("已经将数据: " + data + " 写入磁盘!");
  6. }
  7. }

PrinterWriter 类:

  1. package org.artmansoft.demo;
  2. public class PrinterWriter implements IWriter {
  3. public void write(String data) {
  4. //这里是实现写入打印机的代码,为简便起见,略过
  5. System.out.println("已经将数据: " + data + " 写入打印机!");
  6. }
  7. }

DataServer 类:

  1. package org.artmansoft.demo;
  2. public class DataServer {
  3. private String data;
  4. private IWriter writer; //这里用了接口 IWriter,不论写入任何设备,相应的类都实现了 IWriter 接口,这里不需要改动
  5. public void setData(String data) {
  6. this.data = data;
  7. }
  8. public void write() {
  9. if(this.writer == null){
  10. this.writer = new PrinterWriter(); // 这里需要 new 一个 具体的类对象,如果写入其它设备,需要改动
  11. }
  12. this.writer.write();
  13. }
  14. }

最后是主程序类 App.java:

  1. package org.artmansoft.demo;
  2. public class App {
  3. private static DataService dataService;
  4. public static void main(String[] args) {
  5. dataService = new DataService(); //主程序需要 new 一个数据服务对象
  6. dataService.setData("909099");
  7. dataService.write(); // 已经将数据: 909099 写入打印机!
  8. }
  9. }

(3)用Spring框架进行依赖注入(xml配置)

Created with Raphaël 2.1.2依赖注入过程AppAppcontext:ClassPathXmlApplicationContextcontext:ClassPathXmlApplicationContextdisk:DiskWriterdisk:DiskWriterprinter:PrinterWriterprinter:PrinterWriterdataService:DataServicedataService:DataService(根据配置文件创建)(创建)(创建)(创建,并根据当前配置注入printer对象到writer属性)write()write()

我们先写一个接口:

  1. package org.artmansoft.demo;
  2. public interface IWriter {
  3. public void write(String data);
  4. }

DiskWriter 类

  1. package org.artmansoft.demo;
  2. public class DiskWriter implements IWriter {
  3. public void write(String data) {
  4. //这里是实现写入磁盘的代码,为简便起见,略过
  5. System.out.println("已经将数据: " + data + " 写入磁盘!");
  6. }
  7. }

PrinterWriter 类:

  1. package org.artmansoft.demo;
  2. public class PrinterWriter implements IWriter {
  3. public void write(String data) {
  4. //这里是实现写入打印机的代码,为简便起见,略过
  5. System.out.println("已经将数据: " + data + " 写入打印机!");
  6. }
  7. }

DataServer 类:

  1. package org.artmansoft.demo;
  2. public class DataServer {
  3. private String data;
  4. private IWriter writer; //这里用了接口 IWriter,不论写入任何设备,相应的类都实现了 IWriter 接口,这里不需要改动
  5. public void setData(String data) {
  6. this.data = data;
  7. }
  8. public void setWriter(IWriter writer) {
  9. // writer 由容器注入,并没有在这里 new 一个出来,不论替换到什么输出,这个类不用改动!
  10. this.writer = writer;
  11. }
  12. public void write() {
  13. this.writer.write();
  14. }
  15. }

最后是主程序类 App.java:

  1. package org.artmansoft.demo;
  2. public class App {
  3. private static DataService dataService;
  4. public static void main(String[] args) {
  5. ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //建立一个容器类对象,它会根据配置文件 beans.xml 装入定义的类对象
  6. //dataService = new DataService(); 主程序不需要 new 一个数据服务对象
  7. dataService = DataService context.getBean("dataService"); //向容器要这个对象
  8. dataService.setData("909099");
  9. dataService.write(); // 已经将数据: 909099 写入打印机!
  10. }
  11. }

配置文件 beans.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5. <bean id="disk" class="org.artmansoft.demo.DiskWriter"></bean>
  6. <bean id="printer" class="org.artmansoft.demo.PrinterWriter"></bean>
  7. <bean id="dataService" class="org.artmansoft.demo.DataService">
  8. <!-- 这里把打印机注入-->
  9. <property name="writer" ref="printer"></property>
  10. <!--
  11. 下一行可以注入磁盘
  12. <property name="writer" ref="disk"></property>
  13. -->
  14. </bean>
  15. </beans>

(4)用Spring框架进行依赖注入(标注结合简单的xml配置)

Created with Raphaël 2.1.2依赖注入过程AppAppcontext:ClassPathXmlApplicationContextcontext:ClassPathXmlApplicationContextdisk:DiskWriterdisk:DiskWriterprinter:PrinterWriterprinter:PrinterWriterdataService:DataServicedataService:DataService(根据标注和简单的配置文件创建)(创建)(创建)(创建,并根据当前配置注入printer对象到writer属性)write()write()

我们先写一个接口:

  1. package org.artmansoft.demo;
  2. public interface IWriter {
  3. public void write(String data);
  4. }

DiskWriter 类

  1. package org.artmansoft.demo;
  2. @Component("disk")
  3. public class DiskWriter implements IWriter {
  4. public void write(String data) {
  5. //这里是实现写入磁盘的代码,为简便起见,略过
  6. System.out.println("已经将数据: " + data + " 写入磁盘!");
  7. }
  8. }

PrinterWriter 类:

  1. package org.artmansoft.demo;
  2. @Component("disk")
  3. public class PrinterWriter implements IWriter {
  4. public void write(String data) {
  5. //这里是实现写入打印机的代码,为简便起见,略过
  6. System.out.println("已经将数据: " + data + " 写入打印机!");
  7. }
  8. }

DataServer 类:

  1. package org.artmansoft.demo;
  2. @Component("dataService")
  3. public class DataServer {
  4. private String data;
  5. private IWriter writer; //这里用了接口 IWriter,不论写入任何设备,相应的类都实现了 IWriter 接口,这里不需要改动
  6. @Value("数据的默认值")
  7. public void setData(String data) {
  8. this.data = data;
  9. }
  10. @Autowired //自动注入一个实现了IWriter接口的类的对象
  11. @Qualifier("printer") //如果只有一个 IWriter 实现,此句可省
  12. public void setWriter(IWriter writer) {
  13. // writer 由容器注入,并没有在这里 new 一个出来,如果替换到其它输出,这个类需要改动!
  14. this.writer = writer;
  15. }
  16. public void write() {
  17. this.writer.write();
  18. }
  19. }

最后是主程序类 App.java:

  1. package org.artmansoft.demo;
  2. public class App {
  3. private static DataService dataService;
  4. public static void main(String[] args) {
  5. ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //建立一个容器类对象,它会根据配置文件 beans.xml 装入定义的类对象
  6. //dataService = new DataService(); 主程序不需要 new 一个数据服务对象
  7. dataService = DataService context.getBean("dataService"); //向容器要这个对象
  8. dataService.setData("909099");
  9. dataService.write(); // 已经将数据: 909099 写入打印机!
  10. }
  11. }

配置文件 beans.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context.xsd">
  9. <!-- 配置内容被大大简化 -->
  10. <context:component-scan base-package="org.artmansoft.demo" />
  11. </beans>

(5)用Spring框架进行依赖注入(标注结合配置类)

Created with Raphaël 2.1.2依赖注入过程AppAppcontext:AnnotationConfigApplicationContextcontext:AnnotationConfigApplicationContextdisk:DiskWriterdisk:DiskWriterprinter:PrinterWriterprinter:PrinterWriterdataService:DataServicedataService:DataService(根据配置类创建)(创建)(创建)(创建,并根据当前配置注入printer对象到writer属性)write()write()

我们先写一个接口:

  1. package org.artmansoft.demo;
  2. public interface IWriter {
  3. public void write(String data);
  4. }

DiskWriter 类

  1. package org.artmansoft.demo;
  2. @Component("disk")
  3. public class DiskWriter implements IWriter {
  4. public void write(String data) {
  5. //这里是实现写入磁盘的代码,为简便起见,略过
  6. System.out.println("已经将数据: " + data + " 写入磁盘!");
  7. }
  8. }

PrinterWriter 类:

  1. package org.artmansoft.demo;
  2. @Component("disk")
  3. public class PrinterWriter implements IWriter {
  4. public void write(String data) {
  5. //这里是实现写入打印机的代码,为简便起见,略过
  6. System.out.println("已经将数据: " + data + " 写入打印机!");
  7. }
  8. }

DataServer 类:

  1. package org.artmansoft.demo;
  2. @Component("dataService")
  3. public class DataServer {
  4. private String data;
  5. private IWriter writer; //这里用了接口 IWriter,不论写入任何设备,相应的类都实现了 IWriter 接口,这里不需要改动
  6. @Value("数据的默认值")
  7. public void setData(String data) {
  8. this.data = data;
  9. }
  10. @Autowired
  11. @Qualifier("printer")
  12. public void setWriter(IWriter writer) {
  13. // writer 由容器注入,并没有在这里 new 一个出来,如果替换到其它输出,这个类需要改动!
  14. this.writer = writer;
  15. }
  16. public void write() {
  17. this.writer.write();
  18. }
  19. }

最后是主程序类 App.java:

  1. package org.artmansoft.demo;
  2. public class App {
  3. private static DataService dataService;
  4. public static void main(String[] args) {
  5. ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); //建立一个容器类对象,它会根据配置类扫描需要建立对象的类
  6. //dataService = new DataService(); 主程序不需要 new 一个数据服务对象
  7. dataService = DataService context.getBean("dataService"); //向容器要这个对象
  8. dataService.setData("909099");
  9. dataService.write(); // 已经将数据: 909099 写入打印机!
  10. }
  11. }

配置类 AppConfig:

  1. @Configuration
  2. @ComponentScan
  3. public class AppConfig {
  4. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注