国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php框架 > 框架设计 > 初识Spring Framework

初识Spring Framework

来源:程序员人生   发布时间:2015-03-13 08:37:56 阅读次数:3271次

最近在工作用到了Spring框架,由于之前没有接触过Spring,就从Spring的官方文档开始学起。在“Quick Start”介绍了1个使用Spring做依赖性注入(dependency injection)的例子,该例子使用Maven或GRADlE进行管理的。作者之前没有接触过这两个项目管理工具,由于时间紧急,就直接使用了Eclipse编译了这个例子。在Eclipse下的文件结构以下:



(由于没有使用项目管理工具,刚开始只加入了spring-context.jar和spring-core.jar,又根据异常信息导入了commouns-logging.jar、spring-expression.jar和spring-beans.jar。这就是否是项目管理工具的麻烦所在。)

hello/MessageService.java的代码以下:

package hello; public interface MessageService { String getMessage(); }
hello/MessagePrinter.java的代码以下:

package hello; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class MessagePrinter { final private MessageService service; @Autowired public MessagePrinter(MessageService service) { this.service = service; } public void printMessage() { System.out.println(this.service.getMessage()); } }

hello/App.java的代码以下:

package hello; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.*; @Configuration @ComponentScan public class App { @Bean MessageService mockMessageService() { return new MessageService() { public String getMessage() { return "Hello World!"; } }; } public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(App.class); MessagePrinter printer = context.getBean(MessagePrinter.class); printer.printMessage(); } }

编译运行该项目,会有以下输出:



“Quick Start”最后总结说这个充分体现了依赖性注入(dependency injection)的概念,至于如何体现的作者尝试做1下解析,权当对Spring Framework的1个初步认识。

项目的入口是App.java的main函数,在这个函数中首先声明了1个ApplicationContext对象context,并向下转型为AnnotationConfigApplicationContext对象。ApplicationContext是对1个利用(Application)提供配置的核心接口,AnnotationConfigApplicationContext是它的1个实现,可用来处理用@Configuration,@Component和JSR⑶30标注的类。由于App.java使用@Configuration进行了标注,故App.class可以作为AnnotationConfigApplicationContext构造器的的参数。

MessagePrinter printer = context.getBean(MessagePrinter.class);
这句代码通过context的getBean(Class<T>)方法得到了MessagePrinter的1个实例。为何呢得到MessagePrinter类的1个实例呢?看getBean(Class<T>)的API解释:

Return the bean instance that uniquely matches the given object type, if any.

(如果给定的对象唯1匹配,就返回1个bean实例。)

printer.printMessage();
调用MessagePrinter的printMessage()方法,该方法以下实现:

public void printMessage() { System.out.println(this.service.getMessage()); }
实际上是调用了接口MessageService的getMessage()方法,由于App.java中的mockMessageService()方法中的匿名内部类实现了MessageService接口,并在getMessage()方法中返回了“hello,world!”字符串,顾能在结果中输出"hello,world!"。

使人迷惑的是在mockMessageService()方法并没有被显式调用,为什么其匿名内部类能被实例化并输出信息呢?缘由就在于程序中使用的以下Spring标注。

@Configuration 用于标注1个类,表示bean定义的源文件(source);

@Bean 用于标注1个方法,表示1个方法实例化、配置或初始化1个新的对象(Object),这个对象被Spring的控制反转(IoC)容器管理,相当于Spring <bean />XML配置文件中<bean />元素。(详见官方文档)

@ComponentScan  用于标注1个类,表示扫描指定包中的@Component标注的类,并将这些类注册为Spring IoC容器的bean,亦相当于1个<bean />元素;

@Autowired  用于标注setter方法,构造器,包括多个参数的方法,集合等等,用于自动绑定;

@Component  用于标注1个类

由于MessagePrinter中有以下构造器:

@Autowired public MessagePrinter(MessageService service) { this.service = service; }
从这个构造器中可以到MessagePrinter依赖MessgeServie,并用@Autowired标注。这就表示在通过contexnt.getBean(MessagePrinter.class)得到MessagePrinter的1个实例时,会将对MessageService的依赖自动绑定到MessageService类,将查找所有能作为<bean />元素的类(@Component @Configuration标注)或方法(@Bean标注),而在App.java中有以下方法:

@Bean MessageService mockMessageService() { return new MessageService() { public String getMessage() { return "Hello World!"; } }; }
查找到这个方法后会将这个MessageService实现注入到MessagePrinter实例中,从而实现“hello,world!”的输出。

以上就是作者对Spring Framework文档“Quick Start”例子的解析,有不当的地方=请多多指教。


生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生