本文共 13149 字,大约阅读时间需要 43 分钟。
开发应用时常见的问题:
一:代码耦合高public class EmployeeServiceImpl { //如果接口和实现类在同一地方存在,那么就是高耦合,维护难度增加了。 private IEmployeeDao employeeDao = new EmployeeJdbcDaoImpl();}
bean.propertiesemployeeDao=cn.cxjcloud.dao.impl.EmployeeDaoImplpublic class ObjectFactory { public static Object getObject(String name) { //name =employeeDao Properties ps = new Properties(); ps.load(bean.properties); return Class.forName(name).newInstance(); }}public class AServiceImpl { private IEmployeeDao employeeDao = ObjectFactory.getObject();}public class BServiceImpl { private IEmployeeDao employeeDao = ObjectFactory.getObject();}```二:对象之间依赖关系处理繁琐```javapublic class EmpployeeAction { private IEmployeeService service;}------------------------------------------------------public class EmpployeeService{ private IEmployeeDao dao;}
问题:如果对象有很多,且互相存在依赖关系,并且有的对象需要单例模式,有的则需要多个实例,处理起来比较繁琐;
三:事务控制繁琐
思考:如何降低业务逻辑部分之间耦合度,提高程序的可重用性,同时提高开发的效率! --> AOP
EmployeeService{ public void save(...){ 开启事务 dao.save(...); 关闭事务 }public void update(...){ 开启事务 dao.update(...); 关闭事务 }
注意事项:Spring底层原理:xml+dom4j+工厂设计模式+反射
1.简单地说,模块化就是有组织地把一个大文件拆成独立并互相依赖的多个小模块;
2.Spring框架的功能大约由20个模块组成,这些模块按组可以分为:
(1)Core Container(核心容器): ①Beans:负责Bean工厂中Bean的装配,所谓Bean工厂即是创建对象的工厂,Bean的装配也就是对象的创建工作; ②Core:这个模块即是负责IOC(控制反转)最基本的实现; ③Context:Spring的IOC容器,因大量调用Spring Core中的函数,整合了Spring的大部分功能。Bean创建好对象后,由Context负责建立Bean与Bean之间的关系并维护。所以也可以把Context看成是Bean关系的集合; ④SpEl:即Spring Expression Language(Spring表达式语言);(2)Data Access/Integration(数据访问/集成):
① JDBC:对JDBC的简单封装; ② ORM:支持数据集成框架的封装(如Mybatis,Hibernate); ③ OXM:即Object XML Mapper,它的作用是在Java对象和XML文档之间来回转换; ④ JMS:生产者和消费者的消息功能的实现; ⑤ Transations:事务管理;(3)Web与远程调用:
① WebSocket:提供Socket通信,web端的的推送功能; ② Servlet:Spring MVC框架的实现; ③ Web:包含web应用开发用到Spring框架时所需的核心类,包括自动载入 WebApplicationContext特性的类,Struts集成类、文件上传的支持类、Filter类和大量辅助工具类; ④ Portlet:实现web模块功能的聚合(如网站首页(Port)下面可能会有不同的子窗口(Portlet));(4)AOP:面向切面;
(5)Aspects:同样是面向切面的一个重要的组成部分,提供对AspectJ框架的整合;
(6)Instrumentation(设备):相当于一个检测器,提供对JVM以及对Tomcat的检测;
(7)Messaging(消息):Spring提供的对消息处理的功能;
(8)Test(测试):我们在做单元测试时,Spring会帮我们初始化一些测试过程当中需要用到的资源对象;
第一步:导入Spring相关jar包
resources中:spring-framework-4.1.2.RELEASE中文文档参考:Spring-Reference_2.5_zh_CN.chm
1.我们可以先导入核心包(core)与beans包:2.导包的时候注意,现在使用Spring,要完成最小导包,即:需要什么jar包,我们就导入什么jar包,用到了其他功能,再添加相应jar包。这个对咱们认识框架的包是非常有帮助的。不然以后由于出现问题自己都不知道应该怎么解决;
第二步:导入Spring配置文件
第三步:编写逻辑代码
1.准备一个普通的Java类(MyBean)public class MyBean { public void hello(){ System.out.println("hello spring..."); }}
第四步:将这个类交给Spring去管理即注册到Spring容器中
@Testpublic void testHelloSpring() throws Exception { /** *我们第一步是要启动框架,而启动框架则需要拿到Spring的核心对象 *咱们学习的第一个核心对象是BeanFactory : 顾名思义,这是一个创建Bean的工厂 *而Bean工厂创建对象又必需拿到配置文件中的数据 *因为:我们的第一步读取配置文件,拿到BeanFactory工厂 */ //第一步:读取资源文件 Resource resource = new ClassPathResource("applicationContext.xml"); //第二步:拿到核心对象 BeanFactory BeanFactory factory = new XmlBeanFactory(resource);}
spring-context-4.1.2.RELEASE.jar -- 上下文spring-expression-4.1.2.RELEASE.jar -- Spring表达式语言
//加载工程classpath下的配置文件实例化String conf = "applicationContext.xml";ApplicationContext factory = new ClassPathXmlApplicationContext(conf);
方式一:通过id直接拿到相应的Bean对象
//通过xml中配置的id拿到对象MyBean bean = (MyBean)factory.getBean("myBean");System.out.println(bean);
方式二:通过id与对象的Class对象拿到Bean对象(推荐使用)
//通过id与对象的class拿到Bean对象MyBean bean = factory.getBean("myBean",MyBean.class);System.out.println(bean);
联系:
1.ApplicationContext是BeanFactory的子类,拥有更多的功能与方法; 区别: 1.ApplicationContext默认是在读取配置文件的时候就会根据配置创建Bean对象(迫切加载)。而BeanFactory是在使用的时候才进行对象的创建(懒加载/延迟加载) 扩展: 1.我们在使用ApplicationContext的时候,可以通过配置让它也变成与BeanFactory一样的懒加载: 配置一:让所有Bean都变成懒加载,只需要在标签中加入default-lazy-init=“true”:配置二:让其中一个Bean变成懒加载,在标签中加入lazy-init=“true”:
顾名思义:在xml中进行配置,但是这种方式必须有对应的setter方法,所有这种注入方式又称之为属性注入或setter方法注入;
public class MyBean{ private OtherBean otherBean; public void hello(){ otherBean.hello(); } public void setOtherBean(OtherBean otherbean){ this.OtherBean = OtherBean }}public class OtherBean{ public void hello(){ System.out.println("otherbean hello"); }}//xml配置://测试:main方法测试//加载工程classpath下的配置文件实例化 String conf = "applicationContext.xml"; ApplicationContext factory = new ClassPathXmlApplicationContext(conf);
顾名思义:通过注解实现注入,这种方式可以将注解写在setter方法上,也可以写在字段上,如果写在字段上可以不需要setter方法;
@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;
public class MyBean{ @Autowired //默认按照名称,名称找不到类型匹配 @Qualifier("otherBean1")//可以使用这个注解指定Bean的名称 private OtherBean otherBean; public void hello(){ otherBean.hello(); }}public class OtherBean{ public void hello(){ System.out.println("otherbean hello"); }}//xml配置:
@Resource由J2EE提供,需要导入包javax.annotation.Resource,Spring支持该注解
public class MyBean{ @Resource //默认按照名字匹配【名字对了,类型也必须一致】,然后按照类型匹配//@Resource(name="otherBean1")//指定Bean的名称 private OtherBean otherBean; public void hello(){ otherBean.hello(); }}public class OtherBean{ public void hello(){ System.out.println("otherbean hello"); }}
注意事项:在实例化Bean和注入Bean对象的同时,不要将xml方式和注解方式进行混用,要么都用xml方式【今天用】,要么都用注解方式【明天学完全注解就可以用了】;
单元测试在我们的软件开发流程中占有举足轻重的地位;
而且目前基于Java 的企业应用软件来说,Spring 已经成为了标准配置,那么如何在Spring框架中更好的使用单元测试呢?
Spring框架提供了对单元测试(junit4)的强大支持,我们不用在使用传统的单元测试去测试Spring功能。通过SpringJunit测试,使用注解帮我们读取配置文件和赋值,简化测试代码,提高测试效率;
三大框架整合的时候如果Spring的配置文件不能读取,那么整个项目是跑不起来的, 而Spring的测试可以让我们在不启动服务器的情况下,使用注解读取相应的配置文件,把项目跑起来;
第一步:导入相应的包
spring-test-4.1.2.RELEASE.jar -- 测试包spring-aop-4.1.2.RELEASE.jar -- AOP包
注意:测试包依赖AOP,所以需要导入AOP的jar包,如果没有导入会报错:
第二步:编写测试类和方法
注解: @RunWith:表示先启动Spring容器,把junit运行在Spring容器中; @ContextConfiguration(“classpath:applicationContext.xml”):表示从CLASSPATH路径去加载资源文件; @Autowired:表示自动装配,自动从Spring容器中取出对应bean赋值给当前使用的属性; Spring测试代码:/** * @RunWith:代表开启Spring的测试 * SpringJUnit4ClassRunner:代表是Junit4的测试环境 * * @ContextConfiguration:找到我们的核心配置文件 * 特别注意这里路径: * 方式一(web工程,正式开发时使用): * /cn/cxjcloud/_02_test/applicationContext.xml → 从当前类所在包找(不建议使用) * classpath:cn/cxjcloud/_02_test/applicationContext.xml → 从classpath的根目录开始(正式开发) * 方式二(测试的时候使用): * applicationContext.xml → 当前类所在的包下面开始查找 * 方式三(测试的时候使用): * 注解后面不写名称 → 在当前目录下来创建xml的名称为:测试类名-Context.xml * 例:SpringTest-Context.xml。使用这种方式,这种写法好处是@ContextConfiguration可以不加参数 * * @author Administrator */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class SpringTest { /** * 现在的测试环境应该是这样的 * Spring环境自行启动,所有的核心对象已经处于Spring之中,都应该由Spring自己来创建 * @Autowired的意思是自动注入,ApplcationContext这个类是Spring内部存在的,它也是一个Bean, * Spring可以把它创建出来,在它看到上面的这个标签后,再把创建的Bean注入进来 */ @Autowired private ApplicationContext context; /** * 这个TestBean我们已经在Spring中配置好。交给Spring来管理 * Spring即可以来创建这个对象,然后将这个对象赋值给这个成员变量 */ @Autowired private TestBean testBean; @Test public void testGetBean() throws Exception { System.out.println(testBean); }}
小结:Spring测试让测试变得更加简单,需要注意配置文件的位置,需要了解几个注解: @RunWith(SpringJunit4ClassRunner.class) @ContextConfiguration(“classpath:applicationContext.xml”) @AutoWired
指的是我们配置的Bean是单例还是多例/原型
通过Bean元素中的scope属性指定:
singleton:默认值,单例 prototype:多例3.其他属性值:(一般都不用)
1.Spring中所有bean对象全部懒加载:配置文件的根对象中添加default-lazy-init为true
2.单个Bean对象懒加载/延迟加载
Bean对象的生命周期指的是:从对象创建、初始化、调用执行到销毁的一个过程;
不同作用域的Bean,生命周期有所区别:
(1)Spring管理的Bean对象默认是单例的; (2)Bean对象的实例化和初始化: ①实例化实质是Spring容器调用Bean的无参构造创建Bean对象; ②初始化实质上是Spring容器调用指定的初始化方法; ③BeanFactory管理的Bean默认是在使用的时候才创建Bean对象,即延迟加载,而AppliacationContext管理的Bean默认是在容器创建的时候就会创建Bean对象,即迫切加载; (3)Bean对象的销毁: ①实质上是Spring容器调用指定的销毁方法(并不是真正意义上的销毁Bean对象); ②在容器关闭的时候(ApplicationContext对象没有close方法,其实现类有),Spring 容器会自动调用指定的销毁方法;可以通过bean元素的init-method和destroy-method属性指定初始化方法和销毁方法。但是一般我们自己不会来配置这个生命周期。而这个基本上Spring自身来使用,例如在Spring操作连接池的时候,它会在DateSource销毁的时候执行;
三层架构咱们前面都已经给大家讲解过,咱们开发把整个操作分成三层:
表现层设计:
Controller层: |-- 无需接口(controller包) – XxxController – 例如:UserControllerorg.springframework.web.context.ContextLoaderListener Servlet中编写:@WebServlet("/get")public class UserController extends HttpServlet{ private ApplicationContext context; private IUserService service; @Override public void init() throws ServletException { System.out.println(111); if(context==null){ context=WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); } service = context.getBean("service", UserServiceImpl.class); }} contextConfigLocation classpath:applicationContext.xml
5.部署测试
注意:使用WebApplicationContextUtils要导入web包;转载地址:http://jrcmf.baihongyu.com/