1 / 35

软件技术专业 熊君丽

第 2 章: Spring IOC 容器. 软件技术专业 熊君丽. 2.1 IOC 概述. Inverse of Control,IoC, 是 spring 容器的内核, AOP ,声明式事务都是在此基础上开花结果的。所谓 IOC ,就是通过容器来控制业务对象之间的依赖关系,而非传统的使用代码控制。这也就是反转控制的概念:控制权由应用代码中转到了外部容器,控制权的转移,就是反转。控制权的转移带来的好处是降低了业务对象之间的依赖关系。. 2.2 BeanFactory & ApplicationContext.

ophira
Download Presentation

软件技术专业 熊君丽

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第2章:Spring IOC 容器 软件技术专业 熊君丽

  2. 2.1 IOC概述 • Inverse of Control,IoC,是spring容器的内核,AOP,声明式事务都是在此基础上开花结果的。所谓IOC,就是通过容器来控制业务对象之间的依赖关系,而非传统的使用代码控制。这也就是反转控制的概念:控制权由应用代码中转到了外部容器,控制权的转移,就是反转。控制权的转移带来的好处是降低了业务对象之间的依赖关系。 广东科学技术职业学院

  3. 2.2 BeanFactory & ApplicationContext • Spring 通过一个配置文件描述bean之间的依赖关系,利用java语言的反射功能实例化bean并建立之间的依赖。 • Bean 工厂是spring框架最核心的接口,它提供了高级Ioc的配置机制。他就是IOC容器,而 ApplicationContext称为应用上下文,有时也被称为spring容器。Spring的应用者面对的是applicationContext. 广东科学技术职业学院

  4. 2.2.1 BeanFactory 介绍 • 类的通用工厂,可以创建并管理各种类的对象。POJP,普通的java对象,只要可以被spring容器实例化并管理的java类都可以称为bean。 • 示例2-2-1如下(录像) • 1 创建 car类:属性brand,color,maxSpeed • 2 撰写beans.xml,spring的配置文件 广东科学技术职业学院

  5. Beans.xml • <?xml version="1.0" encoding="UTF-8"?> • -<beans xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"> <bean p:maxSpeed="200" p:brand="红旗CA72" destroy-method="myDestory" init-method="myInit" class="com.smart.Car" id="car"/> • <!-- bean id="car" class="com.smart.beanfactory.Car" init-method="myInit" destroy-method="myDestory" p:brand="红旗CA72"/ --> • </beans> 广东科学技术职业学院

  6. 3 获取bean代码如下:演示2-1,2-2(录像) • public class BeanFactoryTest { • public static void main(String[] args) throws Throwable{ • ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); • Resource res = resolver.getResource("classpath:com/smart/beanfactory/beans.xml"); • System.out.println(res.getURL()); • BeanFactory bf = new XmlBeanFactory(res); • System.out.println("init BeanFactory."); • Car car = bf.getBean("car",Car.class); • System.out.println("car bean is ready for use!"); • car.introduce(); • } • } 装载spring配置信息并启动IOC容器 初始化配置文件中定义的Car 广东科学技术职业学院

  7. 2.2.2 Application Context ApplicationContext ctx=new FileSystemXmlApplication(“”) 如果不显示指定资源类型前缀,将路径解析成文件系统 在初始化应用上下文时实例化所有实例 Spring支持基于类注解的配置方式,如下例: import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.smart.Car; @Configuration public class Beans { @Bean(name = "car") public Car buildCar() { Car car = new Car(); car.setBrand("红旗CA72"); car.setMaxSpeed(200); return car; } } 演示2-3,2-4 广东科学技术职业学院

  8. 类启动器 • publicclass BeanFactoryTest { • /** • * @param args • */ • publicstaticvoid main(String[] args) { • // TODO Auto-generated method stub • /*ResourcePatternResolver resolver=new PathMatchingResourcePatternResolver(); • Resource res=resolver.getResource("classpath:beans.xml"); • BeanFactory bf=new XmlBeanFactory(res);*/ • ApplicationContext ctx=new AnnotationConfigApplicationContext(Beans.class); • Car car=ctx.getBean("car",Car.class); • System.out.println(car.getBrand()); • } • }

  9. WebApplicationContext 该类允许从相对于web根目录的路径中装载配置文件,他的初始化需要ServletContext实例,也就是说它必须在拥有web容器的前提下才能完成启动的工作。 ContextLoaderListener:ContextLoader是一个工具类,用来初始化WebApplicationContext,其主要方法就是initWebApplicationContext, ContextLoader是把WebApplicationContext(XmlWebApplicationContext是默认实现类)放在了ServletContext中,ServletContext也是一个“容器”,也是一个类似Map的结构 。步骤如下: 1配置web.xml文件 (包括监听器+log4j) <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/beans.xml</param-value> </context-param> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/log4j.properties</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>log4jConfigServlet</servlet-name> <servlet-class>org.springframework.web.util.Log4jConfigServlet</servlet-class> </servlet> 广东科学技术职业学院

  10. 续2-2-2-1 • 2将beans.xml文件放在WEB-INF下 • <bean id="car1" class="com.Car" p:brand="mao" p:color="black" p:maxSpeed="200"/> • 3将web访问放入一个action中 • WebApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(sc); • Car boss=ac2.getBean("car1",Car.class); • System.out.println(boss.getBrand()); • returnSUCCESS; • 4http://localhost:8080/test/user访问 • 演示录像2-2-2-1,源代码见2-2-2-1

  11. 2-2-2-1,如果beans.xml文件改成基于java类注解的配置方式,如何修改呢?源文件见2-2-2-1 的web1.xml,另使用Beans.java文件,录像,注解修改2-2-2-1 • <context-param> • <param-name>contextClass</param-name> • <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> • </context-param> • <context-param> • <param-name>log4jConfigLocation</param-name> • <param-value>/WEB-INF/log4j.properties</param-value> • </context-param> • <context-param> • <param-name>contextConfigLocation</param-name> • <param-value>com.Beans</param-value> • </context-param> • <listener> • <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> • </listener> • <servlet> • <servlet-name>log4jConfigServlet</servlet-name> • <servlet-class>org.springframework.web.util.Log4jConfigServlet</servlet-class> • </servlet>

  12. 2.2.3资源加载 1 类路径classpath: 2 文件系统file: 3 Web方式:http:// 4 ftp 5 没有前缀:根据ApplicationContext具体实现类采用对象类型的Resource 演示2-2-3(录像)web访问方式 1 将 beans.xml拷贝到web工程的webroot下 2 访问源码: ResourcePatternResolver resolver=new PathMatchingResourcePatternResolver(); Resource res=resolver.getResource("http://localhost:8080/test/beans.xml"); BeanFactory bf=new XmlBeanFactory(res); Car car=bf.getBean("car1",Car.class); System.out.println(car.getBrand()); 广东科学技术职业学院

  13. Ant风格的资源地址 • 支持三种匹配符 • 1 ?:匹配文件名中的任意一个字符 • 2*:匹配文件名中的任意个字符 • 3**:匹配多层路径 • 例子见课本P39

  14. 2.3bean装配 Spring容器成功启动的条件: • Spring框架的类都已经放到应用程序的类路径下 • 应用程序为spring提供完备的bean配置信息 • Bean的类都已经放到应用程序的类路径下 • Spring容器高层视图 广东科学技术职业学院

  15. Bean的配置信息 • 1 bean的实现类 • 2 bean的属性信息 • 3 bean的依赖关系 • 4 bean的行为配置 • 讲解P40图2-1spring容器高层视图

  16. 2.3.1 bean基本配置 • 装配一个bean • <bean id=“car” class=“com.Car”> Bean名称 Bean类名 广东科学技术职业学院

  17. Bean的命名 1 使用id,注意命名规范 2 使用name,可以使用任意字符,并且可以重复,但后面的bean会覆盖前者。 3 不使用id或者name,spring自动将全限定类名作为bean的名称 广东科学技术职业学院

  18. 2.3.2依赖注入 • 属性注入 set,get,演示 • <bean id="car1" class="com.Car"> • <property name="brand"><value>ca23</value></property> • <property name="color"><value>red</value></property> • <property name="maxSpeed"><value>233</value></property> • </bean> • 构造函数注入 • 构造函数注入是除属性注入之外的另一种常用的注入方式,它保证一些必要的属性在bean实例化时就得到设置,并且确保了bean实例在实例化后就可以使用。 • (1)按类型匹配入参。代码2-11,演示2-11

  19. (2)按索引入参,演示 • <bean id="car1" class="com.Car"> • <constructor-arg index="0" value="ca"/> • <constructor-arg index="1" value="red"/> • <constructor-arg index="2" value="34"/> • </bean> • (3)按类型匹配和索引入参 • (4)通过自身反射类型匹配入参 • <bean id="boss" class="com.Boss"> • <constructor-arg ><value>ming</value></constructor-arg> • <constructor-arg ><ref bean="car1"/></constructor-arg> • </bean> • 总结:指定类型和索引入参不失为一个好习惯

  20. 循环依赖问题 • 当两个bean都采用构造函数注入,而且都通过构造函数入参引用对方,就会发生类似线程死锁的循环依赖问题。 • P47 演示 • 总结:解决这个问题,将构造函数注入方式调整为属性注入方式即可。

  21. 2.3.3注入参数详解 • Spring配置文件中,用户可以使用简单类型,也可以使用集合复杂数据类型,还可以注入其他bean。 • 简单类型:代码P48:2-15 • 引用其他bean:ref元素 • Bean:可以引用同一容器或父容器的bean • Local:只能引用同一容器的bean • Parent:引用父容器的bean,示例2-3-3,源码2-3-3

  22. 集合类型: • (1)list 演示 源码2-3-3-1 • 拓展练习:(2)Map (3)properties

  23. (4) util命名空间配置集合类型:配置一个集合类型的bean 示例2-3-3-3 • 步骤1:配置spring文件 • <beans • xmlns="http://www.springframework.org/schema/beans" • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" • xmlns:util="http://www.springframework.org/schema/util" • xmlns:p="http://www.springframework.org/schema/p" • xsi:schemaLocation="http://www.springframework.org/schema/beans • http://www.springframework.org/schema/beans/spring-beans-3.0.xsd • http://www.springframework.org/schema/util • http://www.springframework.org/schema/util/spring-util-3.1.xsd"> • <util:list id="fav1" list-class="java.util.LinkedList"> • <value>read</value> • <value>play</value> • </util:list><beans>

  24. 步骤2:访问 • LinkedList l=bf2.getBean("fav1",java.util.LinkedList.class); • Iterator it=l.iterator(); • while(it.hasNext()) • System.out.println(it.next());

  25. 简化配置方式 • <p>命名空间,添加xmlns:p=“” • 演示并访问P52 代码2-17 • P:属性名=“” • P:属性名-ref=“” • 自动装配(不建议使用) • Spring容器可以按照规则对容器中的bean进行自动装配。类型如下:byName,byType,constructor,autodetect

  26. 2.3.4 • Bean作用域: • Scope=“” • P54五种选择:singleton,prototype,request,session,globalSession

  27. 2.3.5基于注解的配置 • 1 使用注解定义bean:合并bean的定义信息和实现类 • @component(“car”) • @repository用于对dao实现类进行注解 • @service用于对service实现类进行注解 • @controller用于对controller实现类进行注解 • 2 使用注解配置信息启动spring容器:context命名空间P55,它提供了通过扫描类包以应用注解定义bean的方式,spring容器将会扫描这个基类包里的所有类。 • Component-scan:base-package指定一个需要扫描的基类包,reource-pattern属性过滤出特定的类,演示录像

  28. 自动装配bean • Spring通过@autowired注解实现bean的依赖注入 • @service • Public class LogonService • {@autowired • Private logDao logDao; • @autowired(required=false) • @qualifier(“userDao”) • Private UserDao userDao; • } 定义一个service 分别注入Logdao及userdao的bean Spring容器找不到bean时不抛出异常 限定bean的名称

  29. 2.3.6基于java类的配置javaConfig • 使用java类提供bean定义信息 • 2-21 • @configuration • @bean • 不同类中引用bean,只需使用,拓展练习 • @autowired • 如果使用 • @scope(“prototype”),则每次调用返回一个新的bean

  30. 直接通过@configuration类启动spring容器,例子2-3-6,演示直接通过@configuration类启动spring容器,例子2-3-6,演示 • @Configuration • publicclass BeanFactoryTest { • @Bean • public Car car() • {returnnew Car();} • @Bean • public Boss boss() • { • Boss boss=new Boss(); • boss.setCar(car()); • return boss; • } • publicstaticvoid main(String[] args) { • ApplicationContext ac2 = new AnnotationConfigApplicationContext(BeanFactoryTest.class); • Boss b=ac2.getBean(Boss.class); • System.out.print(b.getCar().getBrand()); • } • }

  31. 引用不同配置类中定义的bean,例子2-3-6-1,演示引用不同配置类中定义的bean,例子2-3-6-1,演示 • 1 CarConfig中定义 car • @Configuration • publicclass AppTest { • @Bean • public Car car() • {returnnew Car();} • } • 2 BossConfig中定义Boss,boss使用 1 中定义的 car • @Configuration • @Import(AppTest.class) • publicclass Logon { • @Autowired • private AppTest apptest; • @Bean • public Boss boss() • { Boss boss=new Boss(); • boss.setCar(apptest.car()); • return boss;} • } • 3 调用 2中定义的boss,显示 car的信息。

  32. 多编码方式加载多个配置类 • AnnotationConfigApplicationContext ac2 = new AnnotationConfigApplicationContext(); • ac2.register(AppTest.class); • ac2.register(Logon.class); • ac2.refresh(); • Boss boss=ac2.getBean(Boss.class); • Car car=ac2.getBean(Car.class); • System.out.print(car.getBrand()); • 或者@Import()组装到一个类中

  33. 通过xml配置文件引用@configuration的配置2-28 • <context:component-scan> 通过configuration配置类引用xml配置信息 • @importResource(“classpath:com/smart/conf/beans2.xml”) • @autowired

  34. 2.3.7不同配置方式的比较 • 基于xml配置:DataSource,SessionFactory,无法在类中标注注解;命名空间的配置 • 基于注解配置:bean的实现类是当前项目开发的,可以直接在java类中使用基于注解的配置 • 基于java类配置:可以通过代码方式控制bean初始化的整体逻辑,通常适合实例化逻辑较为复杂的bean。

  35. Thank You !

More Related