Spring笔记(一)——xml方式实现IoC和DI
来源:互联网 发布:产品网站源码 编辑:程序博客网 时间:2024/06/06 00:51
javaweb开发中,几乎离不开各种开源框架的支持。
javaweb的开发分为三个层次:
WEB层 (表现层)
业务层 – Bean管理:(IOC)
持久层 – Spring的JDBC模板.ORM模板用于整合其他的持久层框架
在这三个层次中,常用的框架结构有SSH和SSM。无论是SSH还是SSM,业务层都是由Spring来实现的。因此,Spring框架对于javaweb开发非常重要。1.Spring简介
- Spring是一个开源框架
- Spring是于2003 年兴起的一个轻量级的Java开发框架,由Rod Johnson在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。
- 它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。
- Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以 从Spring中受益。
1.1 Spring的特点
* 方便解耦,简化开发 * Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理* AOP编程的支持 * Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能* 声明式事务的支持 * 只需要通过配置就可以完成对事务的管理,而无需手动编程* 方便程序的测试 * Spring对Junit4支持,可以通过注解方便的测试Spring程序* 方便集成各种优秀框架 * Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持* 降低JavaEE API的使用难度 * Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低
2.Spring之IoC技术简介
IoC(Inverse of Control),控制反转,将对象的创建权反转给Spring,解决程序耦合性高的问题。
平常的开发中,我们创建一个对象,必须使用new这个关键词来完成。在javaweb的三层开发结构中,三个不同的层次的类之间进行调用。如果都使用new这个关键字来创建对象的实例。那么程序的耦合性会非常高,后期维护会很麻烦。
Spring的IoC技术,帮开发者创建和管理对象。只需要在配置文件中引入先关类的全路径,那么Spring会通过反射来帮助我们创建对象。我们不需要new对象,便可以安安心心的使用了。
2.1 需要导入的jar包
具体的jar包可以去spring的官网或者一些开源社区上去下载。其中第一个包是日志的jar包。
3. 代码实现IoC
创建两个测试类,一个是service层的类,一个是dao层的类。service层测类调用dao层的类。一般开发中,这两个类最好各自实现自己的接口,方便解耦。
public class MydaoImpl implements Mydao { public void save() { System.out.println("这里是持久层"); }}
public class MyServiceImpl implements MyService { private MydaoImpl myDao; private String name; private int age; private ArrayList<String> list; public void setList(ArrayList<String> list) { this.list = list; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setMyDao(MydaoImpl myDao) { this.myDao = myDao; } @Override public void saveUser() { System.out.println("业务层保存用户"); } public void printInfo(){ System.out.println("age-"+age+"name-"+name); } public void testDI(){ myDao.save(); } public void printList(){ for (String str : list) { System.out.println(str); } }}
3.1 spring实现IoC的配置文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="myservice" class="com.mq.service.MyServiceImpl"></bean></beans>
该xml的名称为applicationContext.xml,名称可以改,但一般都为applicationContext。一般放在src目录下。
每一个需要被管理的类,放在在bean标签中进行配置,class是该类的全路径。id是给该类设置一个唯一的标志。
3.2 测试
public class MyTest { @Test public void f1(){ // 使用Spring的工厂: ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // 通过工厂获得类: MyServiceImpl userService = (MyServiceImpl) applicationContext.getBean("myservice"); userService.saveUser(); }}
测试结果:
11:49:19,413 INFO ClassPathXmlApplicationContext:578 - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@46f5f779: startup date [Fri Jul 14 11:49:19 CST 2017]; root of context hierarchy11:49:19,464 INFO XmlBeanDefinitionReader:317 - Loading XML bean definitions from class path resource [applicationContext.xml]业务层保存用户
在调用MyServiceImpl的saveUser方法中,没有创建MyServiceImpl的实例,就可以直接调用该方法了。因为Spring已经帮我们创建了该类的实例对象。
这就是一个最简单的Spring实现IoC的例子。
4. DI
DI ( Dependency Injection),依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件中!!
最常见的场景是,A类需要调用B类的方法,B类是A类的成员属性。并且要提供set方法。首先A类和B类都必须在applicationContext.xml配置文件中进行配置。
在MyServiceImpl有三个属性,其中myDao是一个类的引用。这种形式在开发中非常常见。具体代码上面已经给出。
4.1 依赖注入的配置文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="myservice" class="com.mq.service.MyServiceImpl"><property name="name" value="张三"/><property name="age" value="15"/><property name="myDao" ref="mydao"></property></bean><bean id="mydao" class="com.mq.dao.MydaoImpl"></bean></beans>
对于MydaoImpl和MyServiceImpl都进行了配置。在bean标签下,有property子标签,该标签就是用来配置依赖注入的。
property标签中,name表示在该类中的属性名称,该值必须和MyServiceImpl的属性一致。value表示给该属性赋值,如果该属性是基础类型或者String类型的话。ref表示引用。后面必须是另外一个已经配置的类的id值。
简而言之,在property标签中,name表示属性。如果属性是包括String类型在内的基础类型,使用value直接进行赋值。如果是该属性是其他类的引用,那么就使用ref。
测试结果:
public class MyTest { @Test public void f1(){ // 使用Spring的工厂: ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // 通过工厂获得类: MyServiceImpl userService = (MyServiceImpl) applicationContext.getBean("myservice"); //userService.saveUser(); userService.printInfo(); userService.testDI(); }}
12:12:09,241 INFO ClassPathXmlApplicationContext:578 - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@52d455b8: startup date [Fri Jul 14 12:12:09 CST 2017]; root of context hierarchy12:12:09,287 INFO XmlBeanDefinitionReader:317 - Loading XML bean definitions from class path resource [applicationContext.xml]age-15name-张三这里是持久层
可见,MyServiceImpl中,我们没有new MyDaoImpl的实例对象,就可以调用MyDaoImpl的方法。
4.2 构造方法注入
这种方式用到的不是特别多,需要提供构造方法。
public class Fruit { private String name; private double money; public Fruit (String name, double money) { this.name = name; this.money = money; } }
依赖注入的配置文件内容:
<bean id="fruit" class="com.mq.bean.Fruit"> <constructor-arg name="name" value="香蕉"/> <constructor-arg name="money" value="100"/> </bean>
4.3数组集合和Properties的注入
以list集合为例,在MyServiceImpl中声明list属性,并且提供set方法。
配置文件中:
<bean id="myservice" class="com.mq.service.MyServiceImpl"><property name="name" value="张三"/><property name="age" value="15"/><property name="myDao" ref="mydao"></property> <property name="list"> <list> <value>吃饭</value> <value>睡觉</value> </list> </property></bean>
其中, 中的内容,就是赋给集合中的元素。
4.3.1 其他集合的注入方式
2. 如果是Set集合,注入的配置文件方式如下: <property name="set"> <set> <value>上班</value> <value>下班</value> </set> </property>3. 如果是Map集合,注入的配置方式如下: <property name="map"> <map> <entry key="香蕉" value="3.8"/> <entry key="橘子" value="2"/> <entry key="苹果" value="1"/> </map> </property>4. 如果是properties属性文件的方式,注入的配置如下: <property name="pro"> <props> <prop key="name">root</prop> <prop key="password">test</prop> </props> </property>
5. Spring的其他标签的配置
bean标签中,除了最为常见的id和class子标签,还有其他标签。
- name:给Bean起个名字。如果没有设置id标签,name可以当做id来使用。
- scope:代表Bean的作用范围。有五个取值。
* singleton -- 单例(默认值)。 * prototype -- 多例,整合Struts2中,Action类是多例的,必须设置此属性。 * request -- 应用在Web项目中,每次HTTP请求都会创建一个新的Bean * session -- 应用在Web项目中,同一个HTTP Session 共享一个Bean * globalsession -- 应用在Web项目中,多服务器间的session
- init-method:创建bean时调用init-method指定的方法
- destroy-method:销毁该bean的实例事调用其指定的方法。
6. 其他
目前都只是在测试的方法中加载applicationContext.xml文件。每执行一次测试的方法,都需要重新加载配置文件,效率会比较低。
在web开发中,也不建议来一次请求,就先加载applicationContext.xml文件,再执行相应的方法。这样效率会非常低。
最好的方法时,在ServletContext创建的时候就加载该配置文件,不用每次请求来了都去加载。因此,需要一个listener进行监听ServletContext的创建。
第一步:首先需要导入spring-web-4.2.4.RELEASE.jar包。
第二步:配置监听器:
<!-- 配置Spring的核心监听器: --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param>
第三步:在请求的方法中使用Bean
WebApplicationContext applicationContext =WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext()); MyServiceImpl myservice= (MyServiceImpl) applicationContext.getBean("myservice") myservice.testDI();
这样,只有在项目启动的时候才会加载配置文件,我们直接在web层的接收请求的方法中,可以通过applicationContext对象直接获取相应的bean对象。
- Spring笔记(一)——xml方式实现IoC和DI
- Spring IOC 学习笔记(一) IoC和DI概述
- Spring IOC 学习笔记(一) IoC和DI概述
- Spring IoC和DI——学习笔记
- Spring IOC和DI笔记
- Spring 使用注解的方式实现IOC和DI(控制反转和依赖注入)
- Spring学习笔记(一)----IoC之DI
- Spring学习笔记(一)----IoC之DI
- Spring应用(一) IOC和DI总结
- Spring回顾(二)注解实现IoC和DI
- Spring IOC、DI、AOP原理和实现
- Spring IOC、DI、AOP原理和实现
- Spring IOC、DI、AOP原理和实现
- Spring笔记(二)——注解方式实现IoC和AOP
- 依赖注入(DI)和控制反转(IOC)的详细讲解 spring容器(spring注解实现,而不是xml配置文件)
- Spring--IoC和DI
- spring--IoC和DI
- spring IOC和DI
- 性能场景设计深度分析
- 如何使用Openlayer发布地图
- cocos2d-x使用jni java调用c++方法(java 调 c++)
- 用Log4j在控制台输出Mybatis中执行的SQL
- UVa 11732-strcmp() Anyone?
- Spring笔记(一)——xml方式实现IoC和DI
- C 语言基础 注释
- 【脚本语言系列】关于Python基础知识协程,你需要知道的事
- Python中如何进行数据分组
- MobX 在 React Native开发中的应用
- iOS10富文本推送--UNNotificationExtension--基础篇
- 洛谷P1427 小鱼的数字游戏
- Spark-Streaming之transform操作,实时黑名单过滤案例
- 源码等资源下载网站