Spring框架简介
Spring框架主要可以分为3个核心内容:
- 容器
- 控制反转(IoC ,Inversion of Control)
- 面向切面编程(AOP ,Aspect-Oriented Programming)
Spring的特点:
组件之间的依赖关系由容器在运行期决定 ,由容器动态的将某种依赖关系注入到组件之中。
参考文章:blog.csdn.net/cainiaowys/article/details/7107925
1.使用容器解决问题:
消除实现依赖一般可以通过添加一个容器类来解决。在例子程序容器代码如下:
//容器类
publicclassContainer {
publicstaticContainer instance;
privateMap components;
publicContainer(){
component =newHashMap();
instance =this;
ReportGenertor reportGenertor =newSMSReportGenertor();
components.put(“reportGenertor”, reportGenertor);
ReportService reportService =newReportService();
components.put(“reportService”, reportService);
}
publicObject getComponent(String id){
returncomponents.get(id);
}
}
使用容器后,模块A的ReportService的属性实现方法也发生了变化。
//服务类变更,降低了耦合
publicclassReportService{
//private ReportGenerator reportGenerator = new SMSReportGenerator();
privateReportGenerator reportGenerator = (ReportGenerator) Container.instance.getComponent(“reportGenerator”);
publicvoidgenerateMonthlyReport(intyear,intmonth) {
...
}
}
这样的话,class都在容器中实现,使用者只需要在容器中查找需要的实例,开发人员修改模块B后(在模块中增加邮件报表生成类MailReportGenerator),只需要在容器类中修改声明(把ReportGenertor reportGenertor = new SMSReportGenertor();改为ReportGenertor reportGenertor = new MailReportGenertor();)即可,模块A不需要修改任何代码。一定程度上降低了模块之间的耦合。
但是,在程序中(ReportGenerator)Container.instance.getComponent(“reportGenerator”)的方法取得容器中SMSReportGenertor的实例,这种用字符(“reportGenerator”)指代具体实现类SMSReportGenertor 的方式并没有完全的解决耦合
2.控制反转与依赖注入
这种反转资源获取方向的思想被称为控制反转(IoC,Inversion of Control),使用控制反转后,容器主动地将资源推送给需要资源的类(或称为bean)ReportService,而ReportService需要做的只是用一种合适的方式接受资源。
ReportService类接受资源的方式有多种,其中一种就是在类中定义一个setter方法,让容器将匹配的资源注入:setter的写法如下:
//为需要依赖注入的类加入一种被称为setter的方法
publicclassReportService{
/*private ReportGenerator reportGenerator =
(ReportGenerator) Container.instance.getComponent(“reportGenerator”); */
privateReportGenerator reportGenerator;
publicvoidsetReportGenerator( ReportGenerator reportGenerator) {
this.reportGenerator = reportGenerator;
}
publicvoidgenerateMonthlyReport(intyear,intmonth) {
...
}
}
在容器中把依赖注入:
//容器类
publicclassContainer {
...
publicContainer ( ) {
component =newHashMap();
instance =this;
ReportGenertor reportGenertor =newSMSReportGenertor();
components.put(“reportGenertor”, reportGenertor);
ReportService reportService =newReportService();
reportService.setReportGenerator(reportGenerator);//使用ReportService的setter方法注入依赖关系
components.put(“reportService”, reportService);
}
...
}
这样一来ReportService就不用管SMSReportGenertor在容器中是什么名字,模块A对于模块B只有接口依赖,做到了松耦合。
Spring IoC容器的XML配置
每个使用Spring框架的工程都会用到容器与控制反转,为了代码复用,Spring把通用的代码独立出来形成了自己的IoC容器供开发者使用:
与上面例子中实现的容器相比,Spring框架提供的IoC容器要远远复杂的多,但用户不用关心Spring IoC容器的代码实现,Spring提供了一种简便的bean依赖关系配置方式------使用XML文件,在上面的例子中,配置依赖关系只要在工程根目录下的“application.xml”编辑如下内容:
XML代码参考:blog.csdn.net/cainiaowys/article/details/7107925
是标准的XML头,xmlns引用的是一些命名空间,两个一般在工程中自动生成。后面的内容由用户输入,主要表示实例化SMSReportGenerator,实例化ReportService并把SMSReportGenerator的对象smsReportGenerator赋值给ReportService的属性reportGenerator,完成依赖注入。
3.用AOP解决问题
Spring框架利用了代理模式的思想,提出了一种基于Java注解(Annotation)和XML配置的面向切面编程方法(AOP ,Aspect-Oriented Programming)简化了编程过程。AOP类似于代理模式。
//切面模块实现
@Aspect//注解1
publicclassLogAspect{
@Before(“execution(* *.*(..))”)//注解2
publicvoidLogBefore(JoinPoint joinPoint)throwThrowable{
log4j.info(“开始:方法”+ joinPoint.getSignature().getName() );
}
@After(“execution(* *.*(..))”)//注解3
publicvoidLogAfter(JoinPoint joinPoint)throwThrowable{
log4j.info(“结束:方法”+ joinPoint.getSignature().getName() );
}
}
实现完切面类后,还需要对Spring工程中的application.xml进行配置以便实现完整的动态代理:
AOP配置XML文件参考:blog.csdn.net/cainiaowys/article/details/7107925