资讯详情

资讯详情

初始Spring 详解

初始Spring绿叶子Spring框架轻量级框架, Java EE的春天,当前主流框架, Spring中春天Spring框架 致力于JavaEE 应用的各种 解决方案, 而不是仅仅专注于某一层的方案, 可以说Spring 是企业级应用开发的一站式俗称一条龙服务Spring针对不同的业务需求,都有不同的解决方案;Spring 贯穿表现层 业务层 持久层然而并不是要取代这些已有的框架而是以高度的开放性与它们无缝整合;企业级应用开发企业级应用指为 商业组织 大型企业而创建部署的;解决方案/应用当前的企业级应用绝不可能是一个个独立系统, 一般都会部署多个进行交互的应用; 同时这些应用又都可能会与, 其它企业相关应用连接.// 构成一个结构复杂跨越 Internet 的分布式企业应用 集群传统Java EE 解决企业级应用 使用 EJB重量级,架构系统而它开发效率 , 开发难度 和 实际性能都令人失望. 所以后面出现了Spring“救世主”形式出现在了 Java程序员面前;EJBEJB是的Enterprise Java Beans技术的简称, 又被称为企业Java Beans。基于分布式事务处理的企业级应用程序的组件但因为学习比较难开发难度大依赖应用服务器运用大量的设计模式而被 淘汰;内容IoC容器 , AOP实现 , 数据访问支持 , 简化 JDBC/ORM 框架 , 声明式事务 , Web集成...Spring 体系结构Spring一共有十几个组件:Spring框架的核心组件只有三个Core、Context和Beans。他们构建起了整个Spring的骨骼架构没有他们就不可能有AOP、Web等上层的特性功能。AOP包(主要提供面向切面编程的实现)Web(主要提供了Web应用开发的支持及针对Web应用的MVC思想实现)ORM为我们之前学的Hibernate以及以后会学到的Mybatis这类持久化框架提供支持还有Spring MVC这个是它自带的一个web视图层可以替代到Sturts2将来我们还会详细的学习这个SpringMVC框架…等等Spring设计理念Spring三个核心组件Core、Context、Beans。如果再再他们三个中选一个核心来那就非Beans莫属了。Spring是面向Bean(Java类)的编程:BOPBean Oriented ProgrammingBean在Spring 中作用就像Object(对象)对OOP(面向对象)的意义一样没有对象的概念就没有面向对象编程Spring中没有Bean也就没有Spring存在意义。就像一次演出舞台都准备好了但是却没有演员一样。Spring解决了一个非常关键的问题他可以让你把对象之间的关系转而使用配置文件来管理也就是他的依赖注入机制而这个注入关系在一个叫Ioc的容器中管理。Spring正是通过把对象包装在Bean中从而达到对这些对象管理以及一系列额外操作的目的。那它是怎么管理这些Bean的呢Spring把所有的Bean及它们之间的依赖关系以配置文件的方式组装起来在一个叫IoCInversion of Control的容器中进行管理这也就是Spring的核心设计思想之一依赖注入机制Spring的另一个核心设计思想叫做AOP ;优点低侵入式设计非入侵式设计基于Spring开发的应用一般不依赖于Spring的类Spring的依赖注入特性使Bean与Bean之间的依赖关系变的完全透明可以统一管理和生成Bean降低了耦合度使用SpringIOC容器将对象之间的依赖关系交给Spring降低组件之间的耦合性让我们更专注于应用逻辑它的面向切面编程aop特性允许将一些通用任务如安全、事务、日志等进行集中式处理;独立于各种应用服务器真正实现一次编写到处运行。并且它还提供了与第三方持久层框架的良好整合并简化了底层数据库访问高度的开放性可以和Struts2、Hibernate、MyBatis、CXF等很多主流第三方框架无缝整合总的来说Spring确实是一个令每个开发人员都值得学习的开发工具。接下来我们就一起在学习过程中体会他的魅力吧。Spring两大核心技术控制反转(IoCInversion of Control ) /依赖注入(DIDependency Injection )面向切面编程(AOPAspect Oriented Programming)控制反转概述由传统的代码实例化操作, 转换为由 Spring容器来操作处理 Bean的实例化操作;(依赖)控制权由应用代码中转到了外部容器控制权的转移是所谓反转。也称依赖注入Dl是面向对象的一种设计理念用来减低程序代码之间的 耦合度;什么是依赖// 值代码中, 通过局部变量, 方法参数, 返回值等.. 建立于对其它对象的调用关系;// 例如在A类方法中 实例化 B类型的对象, 并调用其方法完成某种功能.. 就可以称为 A类依赖于B类;// 几乎所有应用程序,都是由两个及以上的类,通过彼此合作实现完整的功能 . 类于类之间的依赖关系, 增加了程序开发的复杂程度; 我们在开发一个/修改类的时候还需要考虑使用该类的类 的影响;is 是 子类继承父类 即 子类 is 父类;has 包含A类依赖B类 即A类 hasB类;实例demo以汽车为例子需要一个汽车类Cart.JavapublicclassCart{//这里车有两个属性品牌 和 发动机; 因为车是依赖于发动机的所以 有一个发动机类型;//这里发动机是个接口类型,以表示多种发动机可选性;publicStringbrand;//品牌publicFdjfdj;//发动机//初始化publicvoidinit(){System.out.println(品牌this.brand);//打印发动机;fdj.show();}//get/set方法;publicStringgetBrand(){returnbrand;}publicvoidsetBrand(Stringbrand){this.brandbrand;}publicFdjgetFdj(){returnfdj;}publicvoidsetFdj(Fdjfdj){this.fdjfdj;}}发动机接口类Fdj.JavapublicinterfaceFdj{//打印当前发动机; 每一个继承发动机接口的 发动机子类都要实现改方法..publicvoidshow();}发动机接口实现类BenTianFdj.Java本田发动机publicclassBenTianFdjimplementsFdj{Overridepublicvoidshow(){// TODO Auto-generated method stubSystem.out.println(本田发动机);}}SanLingFdj.Java三菱发动机publicclassSanLingFdjimplementsFdj{Overridepublicvoidshow(){System.out.println(三菱发动机);}}实现类Test.JavapublicclassTest{publicstaticvoidmain(String[]args){CartcnewCart();//假设要 大众的品牌c.setBrand(大众);//假设要 三菱发动机则;c.setFdj(newSanLingFdj());//最后结果;c.init();}}// 还记的以前写 Servlet 和 JSP 时候吗三层数据层 业务逻辑层 展示层// 而有时候实体类修改属性, 就要到数据层 —— 业务逻辑层 —— Service… 都要改;// 就像现在这样 Test是展示层 Cart是逻辑层…//发动机接口需要替换将导致 Cart —— Test发送改变; 而且现在 Test中还存在 new Cart…操作导致程序的耦合…// 使程序, 程序不具备优良的**可扩展性 , 可维护性 ** 甚至在开发中将会 , 难以测试;使用工厂模式的方法解决此问题// 加一个 工厂类CartFactory.Java专门用来制作Cart类 对象;publicclassCartFactory{//制作汽车方法;publicCartcreateCart(Stringbrand,Stringfdj){CartcartnewCart();cart.setBrand(brand);if(fdj.equals(本田)){BenTianFdjbennewBenTianFdj();cart.setFdj(ben);}elseif(fdj.equals(三菱)){SanLingFdjsannewSanLingFdj();cart.setFdj(san);}returncart;}}// 修改Test.JavapublicclassTest{publicstaticvoidmain(String[]args){//创建 汽车工厂;CartFactorycartFactorynewCartFactory();//生产汽车对象;CartccartFactory.createCart(大众,三菱);//输出;c.init();}}// 这里CartFactory工厂类就是“控制反转”的思想; Test类中不在出现 new Cart(); 的操作;// 而是交给了第三方工厂来完成此操作; 在如何获取 所依赖的 Cart 对象的方式上,控制权发生了变化反转// 从原来的直接 new Cart(); 到 CartFactory 工厂 .cartFactory(); 这就是控制反转降低了 耦合,但还是有 new Cart(); 操作并不是真正的解决 耦合;// 大量的工厂引入开发过程中,会导致 工作量增加…// Spring 解决了这个问题, 提供了完整的 IOC 实现控制反转, 使开发可以专注于 业务类等操作;使用Spring 修改配置Spring官网上下载:所需要的Spring资源Spring Framework对于一些开发工具其实都已经集成了:开发环境(MyElicpse) 在web项目上 ——右击项目——选择MyElicpse项——project facets [capabilities] 项—— 在选择Install Spring Facet 一个小绿叶标志哦~选中即可自动导入对应的 Jar 包Src下产生对应的 applicationContext.xml (Spring 的配置文件进行依赖注入DI)可以在Src 下专门建一个Source FoIderle文件 resources 名 资源目录; 所有的资源文件都可以放在这儿; Myelicpse 中就相当于就是在Src 下的一样, 不会有任何影响;需要JarSpring运行依赖commons-logging-1.1.1.jar为了方便观察,Bean实例化,采用 lo4j 输出查看log4j-1.2.17.jar 需要对应的 log4j.propertiesSpring 的配置文件applicationContext.xml?xml version1.0 encodingUTF-8?beansxmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:phttp://www.springframework.org/schema/pxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd!-- Spring使用Bean /标签进行依赖注入 完成控制反转,实例化类操作; 属性 id: 值唯一, 表示定义Bean实例的名称; class: 表示定义Bean实例的类型; 值就是表示类的: 引用类路径; Myelicpse: 还可以观察类文件图标有没有出现S 来确定类是否被 Spring容器管理 子元素: property nameBean的属性名 / value基本数据类型,直接赋值/value 或 ref bean复杂数据类型Bean直接引用其ID 即可(就相当于new一样) /property --!-- 因为本田/三菱类并没有属性,所以就这样就完了... --beanidBTclasscom.wsm.spring.BenTianFdj/bean!-- 本田发动机 --beanidSLclasscom.wsm.spring.SanLingFdj/bean!-- 三菱发动机 --beanidcartclasscom.wsm.spring.Cartpropertynamebrandvalue大众/!-- 给基本类型属性brand 直接赋值 --propertynamefdjrefBT/!-- 给复杂类型属性fdj 引用其bean id赋值 --!-- 注意这里表面上是 根据属性名赋值,实际上内部是调用了属性的 setxx(); 被称为 设值注入 所以一定要注意JavaBean命名规范,而且 如果没 get/set 则会编译报错... eg: 如果 namename 则底层调用 setName(); aa 则 setAa();... --/bean/beansTest.Javapackagecom.wsm.spring;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassTest{publicstaticvoidmain(String[]args){//通过 ClassPathXmlApplicationContext 实例化 Spring 上下文;ApplicationContextcontextnewClassPathXmlApplicationContext(applicationContext.xml);//通过 ApplicationContext 的getBean(Bean的Id); 获取对应的Bean 的实例,返回Object类型;Cartc(Cart)context.getBean(cart);//强转为 Cart类型对象;//调用方法;c.init();}/* * ApplicationContext 是一个接口,负责读取Spring 配置文件; * 管理对象加载,维护Bean对象与Bean对象之间的依赖关系; 负责Bean的生命周期; * ClassPathXmlApplicationContext 是 ApplicationContext 的实现类: * 从 classpath路径读取Spring配置文件; * */}面向切面编程(AOPAspect Oriented Programming)上图这个代码非常熟悉把就是基本的业务实现的代码;日志——异常处理——事务控制 都是一个健壮的业务系统所必须的。为了保证系统健壮性可用就要在众多业务方法中反复编写类似的代码; 使原本复杂的代码更加复杂;业务功能的开发者还要关注这些 “额外” 的代码是否处理正确, 遗漏的地方; 如果修改增加新的功能,也可能会导致 业务代码的修改;对这些, 零散的代码, 穿插在业务中的代码操作就是横切逻辑也称为切面为了不受干涉的专注于 业务的代码将这些代码抽离出来放在专门的 方法/类中;便于管理 维护 ,但依然无法彻底的完成 业务 和 切面逻辑 的彻底解耦业务的代码中还要保留调用的 方法();代码这正是 AOP 解决的问题面向切面编程,简单的说就是: 在不改变原来程序基础上为,代码增加新的功能,对代码进行增强处理.设计思想来源于 代理模式(看样子后面得看看设计模式了)原理将复杂的需求分解出不同方面将散布在系统中的公共功能集中解决采用代理机制组装起来运行在不改变原程序的基础上对代码段进行增强处理增加新的功能AOP基本概念切面Aspect切面可以理解为切点和增强组成切面。它包括了横切逻辑的定义也包括了连接点的定义。切入点Pointcut对连接点. 特征进行描述; 可以使用正则表达式简单的说就是连接点的查询条件连接点Join Point程序执行过程中某个具体执行的点 ( 就是核心要执行的方法; )增强处理Advice增强处理又分为 前置增强后置增强环绕增强异常抛出增强最终增强等类型是织入到目标类连接点上的一段程序代码。增强包含了用于添加到目标连接点上的一段执行逻辑又包含了用于定位连接点的方位信息。AOP代理AOP proxyAOP框架创建的对象。一个类被AOP织入增强之后就产生了一个结果类它是融合了原类和增强逻辑的代理类。(代理对象)目标对象Target object增强逻辑 织入的目标类就是被增强的类的对象;织入Weaving将增强添加到目标类具体连接点上的过程。AOP有三种织入的方式编译期织入、类装载期织入、动态代理织入spring采用动态代理织入Spring AOP就是负责实施切面的框架它将切面所定义的横切逻辑织入到切面所指定的连接点中总结在AOP中切面就是与业务逻辑独立但又垂直存在于业务逻辑的代码结构中的通用功能组合切面与业务逻辑相交的点就是切点连接点就是把业务逻辑 离散化后的关键节点即 核心的业务逻辑代码块方法();连接点属于切点是所有切入点的子集增强Advice就是切面在切点上要执行的功能增加的具体操作将增强添加到目标类具体连接点上的过程。这个就叫织入//当然空讲理论当然不是关键, 奉上代码-“_”-// 在上述代码中扩展新增一个类Aop.Java可以理解为:增强处理类, 里面存储增强代码方法();publicclassAop{privateLoggerlogLogger.getLogger(Aop.class);//前置增强 //连接点对象publicvoidbeforeee(JoinPointjoinPoint){log.info(前置,调用joinPoint.getTarget()类,下的方法是joinPoint.getSignature().getName(),方法的参数是:Arrays.toString(joinPoint.getArgs()));}//后置增强 //连接点对象,返回值publicvoidafterReting(JoinPointjoinPoint,Objectresult){log.info(后置,调用joinPoint.getTarget()类,下的方法是joinPoint.getSignature().getName(),方法的参数是:Arrays.toString(joinPoint.getArgs()),方法的返回值是result);}/* JoinPoint 连接点对象; 为了能够在增强方法中获得当前连接点的信息以便实施相关的判断和处理 可以在增强方法中声明一个JoinPoint类型的参数。 Spring会自动注入实现该实例。 通过该实例的getTarget( ) 方法可以得到被代理的目标对象!!! getSignature( )方法返回被代理的目标方法 getArgs( )方法返回传递给目标方法的参数数组。 对于实现后置增强的afterReturning( )方法还可以定义一个参数用于接收目标方法的返回值。 */}Spring 的配置文件applicationContext.xml将增强处理和切入点结合在一起在切入点处插入增强处理完成织入另外在这之前还需要导入aop需要的命名空间Myelicpse可直接在文件格式下选中——Namespaces——打勾?xml version1.0 encodingUTF-8?beansxmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:phttp://www.springframework.org/schema/pxmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd!-- 引入命名空间xmlns:aophttp://www.springframework.org/schema/aop --!-- 省略了之前的代码..注意哦 --!-- aop:config中完成织入 --aop:configaop:pointcutexpressionexecution (public String init())idmypoint/!-- 配置切入点的标签aop:pointcut aop:pointcut的expression属性可以配置切入点表达式切入点表达式支持模糊匹配讲解几种常用的模糊匹配: public * addNewUser(entity.User) “*”表示匹配所有类型的返回值。 public void *(entity.User) “*”表示匹配所有方法名。 public void addNewUser(..) “..”表示匹配所有参数个数和类型。 * com.service.*.*(..) 匹配com.service包下所有类的所有方法。 * com.service..*.*(..) 匹配com.service包及其子包下所有类的所有方法 ....等等; Myelicpse工具也可以根据,一些小箭头 --aop:aspectrefmyLogAop!-- aspect:切面,切入点和增强组成.. ref:引入增强处理类,类对象 --!-- 前置增强 前置的方法名(); 切入点 --aop:beforemethodbeforeeepointcut-refmypoint/!-- 后置增强 后置方法名(); 切入点 返回值参数名; --aop:after-returningmethodafterRetingpointcut-refmypointreturningresult//aop:aspect/aop:config!-- 增强处理类 --beanidmyLogAopclasscom.wsm.aop.Aop/bean/beans
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →