Spring IOC 练习

练习题
实验一 | 通过IOC容器创建对象,并为属性赋值
实验二 | 通过Bean的类型从IOC中获取bean的实例
实验三
3.1使用构造器在IOC中创建bean
3.2通过p名称空间为bean赋值
实验四
4.1正确的为各种属性赋值 测试使用nu11值、 引用类型赋值(引用其他bean、引用内部bean) 集合类型赋值(List、Map、 Properties)
4.2 Util名称空间创建集合类型的bean
4.3级联属性赋值
实验五 | 通过继承实现配置信息的重用
实验六 | 通过abstract属性创建一个模板bean
实验七 | Bean之间的依赖
实验八 | 测试bean的作用域
★实验九
实验十 | 创建带有生命周期方法的bean
实验十一 | 测试bean的后置处理器
★实验十二 | 引用外部属性文件(spring管理连接池)
实验十三 | 基于XML的自动装配(自动赋值)
实验十四 SPEL测试
★实验十五 | 使用注解分别创建Dao,Service,Controller
实验十六 | 指定扫描时不包含的类
实验十七 | 指定扫描时要包含的类
★实验十八 | 使用@Autowired注解实现根据类型的自动装配
★实验十九 | 资源类型的bean不止一个,默认根据@Autowired注解标记的成员变量名作为id查找bean
★实验二十 | 使用@Qualifier注解明确指定目标bean的id
★实验二十一 | 在方法的形参上使用@Qualifier注解
★实验二十二 | @Autowired注解的required属性指定某个属性允许不被设置

TOC

练习题

实验一 | 通过IOC容器创建对象,并为属性赋值


ico.xml

1<?xml version="1.0" encoding="UTF-8"?> 2<beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 5 <bean id="person01" class="per.wzy.spring.Person"> 6 <property name="age" value="18"></property> 7 <property name="name" value="张三"></property> 8 <property name="sex" value="男"></property> 9 </bean> 10</beans>

test.java

1public class ioctest { 2 @Test 3 public void Test(){ 4 5 //创建容器对象 6 //容器中的对象在容器创建完成的时候就已经创建好了(所有的对象都会创建) 7 //同一组件在IOC中是单实例的 8 ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml"); 9 10 //获取对象 11 Person person01 = (Person) context.getBean("person01"); 12 13 System.out.println(person01.getName()); 14 15 } 16}

实验二 | 通过Bean的类型从IOC中获取bean的实例


1//如果IOC容器中这个类型的bean有多个,则查找会报错 2Person person = context.getBean(Person.class); 3//存在多个同类型bean,根据id查找 4Person person = context.getBean("person02",Person.class);

实验三

3.1使用构造器在IOC中创建bean

1 <bean id="person03" class="per.wzy.spring.Person"> 2 <constructor-arg name="name" value="大花"></constructor-arg> 3 <constructor-arg name="age" value="19"></constructor-arg> 4 <constructor-arg name="sex" value="女"></constructor-arg> 5 </bean>
  • 不添加name属性,默认按照构造器中属性顺序赋值
  • 添加index属性,设置位置
  • 添加type属性,设置值的类型,适用于构造器重载的情况

3.2通过p名称空间为bean赋值

  1. 引入p名称空间:beans中添加 xmlns:p="http://www.springframework.org/schema/p"

  2. 使用p名称空间进行赋值

    1<bean id="person05" class="per.wzy.spring.Person" 2 p:age="15" p:name="二花" p:sex="母猪"> 3 </bean>

实验四

4.1正确的为各种属性赋值 测试使用nu11值、 引用类型赋值(引用其他bean、引用内部bean) 集合类型赋值(List、Map、 Properties)

1 **复杂属性赋值** 2 3 4<bean id="person06" class="per.wzy.spring.Person"> 5 <constructor-arg name="age" value="16"></constructor-arg> 6 <!--地址引用 bean--> 7 <!--<constructor-arg name="child" ref="chid01"></constructor-arg>--> 8 <constructor-arg name="child"> 9 <!--对象使用bean标签进行创建--> 10 <bean class="per.wzy.spring.Children"> 11 <property name="sex" value="女"></property> 12 <property name="name" value="翠花"></property> 13 <property name="age" value="2"></property> 14 </bean> 15 </constructor-arg> 16 <constructor-arg name="childrens"> 17 <list> 18 <bean id="child02" class="per.wzy.spring.Children" p:sex="男" p:name="王五" p:age="18"></bean> 19 <ref bean="chid01"></ref> 20 </list> 21 </constructor-arg> 22 <constructor-arg name="name" value="三花"></constructor-arg> 23 <constructor-arg name="sex" value="女"></constructor-arg> 24 25 <!--MAP属性赋值--> 26 <constructor-arg name="map"> 27 <map> 28 <entry key="key01"> 29 <bean class="per.wzy.spring.Children" p:age="18" p:name="华盛顿" p:sex="男"></bean> 30 </entry> 31 </map> 32 </constructor-arg> 33 <constructor-arg name="properties"> 34 <props> 35 <prop key="username">wzy</prop> 36 <prop key="pwd">123456</prop> 37 </props> 38 </constructor-arg> 39 </bean>
  • 赋NULL值,不填写value属性,添加标签
  • 复杂属性赋值均不在value中进行赋值
  • List赋值:添加标签,标签中继续添加其他标签

4.2 Util名称空间创建集合类型的bean

  • 1 <!--添加命名空间导入提示 --> 2 xmlns:context="http://www.springframework.org/schema/context
  • 导入util命名空间

  •   <util:map id="map01">    <entry key="key001">        <bean class="per.wzy.spring.Children">            <!--<constructor-arg name="age" value="15"></constructor-arg>-->            <!--<constructor-arg name="name" value="函数"></constructor-arg>-->            <!--<constructor-arg name="sex" value="男"></constructor-arg>-->            <property name="name" value="111"></property>            <property name="sex" value="男"></property>            <property name="age" value="150"></property>         </bean>    </entry></util:map>
    

4.3级联属性赋值

级联属性:属性的属性


1 <bean name="person07" class="per.wzy.spring.Person"> 2 <property name="child" ref="chid01"></property> 3 <property name="child.age" value="20"></property> 4 </bean>

引用会更改原来bean中的值

实验五 | 通过继承实现配置信息的重用


parent:指定当前bean的配置信息继承于哪个bean

<bean name="person08" class="per.wzy.spring.Person" parent="person06">    <property name="name" value="哈子"></property></bean>

实验六 | 通过abstract属性创建一个模板bean


abstract="true" :这个bean的配置是抽象的,不能获取他的实例,只能用来被继承。

<bean name="person08" class="per.wzy.spring.Person" abstract="true">    <property name="name" value="继承"></property>    <property name="age" value="11"></property>    <property name="sex" value="男"></property></bean>

实验七 | Bean之间的依赖


  • 原本是按照bean的配置顺序创建
  • 使用depends-on决定创建顺序

实验八 | 测试bean的作用域

测试bean的作用域,分别创建单实例和多实例的bean


bean的作用域:指定bean是否单实例,xxx;默认:单实例的
prototype:多实例的
1)、容器启动默认不会去创建多实例bean
2)、获取的时候创建这个bean,每次获取创建一个新的

sing1eton:单实例的;默认的
1)、在容器启动完成之前就已经创建好对象,保存在容器中了。
2)、任何获取都是获取之前创建好的那个对象

★实验九

配置通过静态工厂方法创建的bean,实例工厂方法创建的bean、FactoryBean


bean的创建默认就是框架利用反射new出来的bean实例

<!--1、静态工厂(不需要创建工厂本身) Factory- method=" getAirP1ane"
指定哪个方法是工厂方法
class:指定静态工厂全类名
factory- method:指定工厂方法

1package per.wzy.factory; 2import per.wzy.spring.Car; 3 4public class CarStaticFactory { 5 public static Car getCar(String name){ 6 Car car = new Car(); 7 car.setName(name); 8 car.setColor("Red"); 9 car.setPrice(95650.5); 10 return car; 11 } 12} 13 14<bean name="car01" class="per.wzy.factory.CarStaticFactory" factory-method="getCar"> 15 <constructor-arg name="name" value="崩瓷"></constructor-arg> 16 </bean>

实例工厂方法创建bean对象

1<!--配置实例工厂--> 2 <bean name="CarInterFace" class="per.wzy.factory.CarInterfaceFactory"></bean> 3 4 <!--使用实例工厂创建bean对象--> 5 <!--使用 constructor-arg 给工厂方法负责--> 6 <bean name="car02" class="per.wzy.spring.Car" factory-bean="CarInterFace" factory-method="getCar"> 7 <constructor-arg name="name" value="奥迪"></constructor-arg> 8 </bean>

实验十 | 创建带有生命周期方法的bean

1package per.wzy.spring; 2 3public class Book { 4 5 private String bookname; 6 private String isbn; 7 private double price; 8 9 //自定义初始化方法,不能带有参数,但可以抛出任意异常 10 public void Init(){ 11 System.out.println(" book init ......"); 12 } 13 14 //销毁方法 15 public void Destory(){ 16 System.out.println("book destory ......"); 17 } 18 19 public Book() { 20 } 21 22 public Book(String bookname, String isbn, double price) { 23 this.bookname = bookname; 24 this.isbn = isbn; 25 this.price = price; 26 } 27 28 public String getBookname() { 29 return bookname; 30 } 31 32 public void setBookname(String bookname) { 33 this.bookname = bookname; 34 } 35 36 public String getIsbn() { 37 return isbn; 38 } 39 40 public void setIsbn(String isbn) { 41 this.isbn = isbn; 42 } 43 44 public double getPrice() { 45 return price; 46 } 47 48 public void setPrice(double price) { 49 this.price = price; 50 } 51} 52 53 54 <!--单实例bean:容器启动时自动创建--> 55 <!--多实例bean: 容器启动时不会被创建,获取时创建--> 56 <!--为bean自定义一些生命周期方法,创建或销毁时会使用这些方法--> 57 <bean id="book01" class="per.wzy.spring.Book" 58 destroy-method="Destory" 59 init-method="Init"> 60 <property name="bookname" value="Java编程"></property> 61 <property name="isbn" value="ki154454"></property> 62 <property name="price" value="15.3"></property> 63 </bean>

实验十一 | 测试bean的后置处理器

无论bean是否具有初始化方法,后置处理器都会执行

流程:

  • 编写后置处理器实现类

    package per.wzy.spring;

    import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class MyBeanPostProcessor implements BeanPostProcessor {

    1public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 2 System.out.println(beanName+"即将初始化"); 3 return bean; 4} 5 6public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 7 System.out.println(beanName+"初始化完成"); 8 return bean; 9}

    }

  • 后置处理器注册在配置文件中

    <!--注册后置处理器-->

    <bean id="beanpostprocessor" class="per.wzy.spring.MyBeanPostProcessor"></bean>

输出结果:

1八月 31, 2019 4:06:46 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 2信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5cbc508c: startup date [Sat Aug 31 16:06:46 CST 2019]; root of context hierarchy 3八月 31, 2019 4:06:47 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 4信息: Loading XML bean definitions from class path resource [applicationContext.xml] 5book01即将初始化 6book init ...... 7book01初始化完成 8八月 31, 2019 4:06:48 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose 9信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@5cbc508c: startup date [Sat Aug 31 16:06:46 CST 2019]; root of context hierarchy 10book destory ......

★实验十二 | 引用外部属性文件(spring管理连接池)

context命名空间

1xmlns:context="http://www.springframework.org/schema/context" 2```` 3 4xsi中添加 5 6```xml 7http://www.springframework.org/schema/context 8http://www.springframework.org/schema/context/spring-context-4.2.xsd

外部配置文件

1user=root 2password=www123 3jdbcUrl=jdbc:mysql://localhost:3306/test 4driverClass=com.mysql.jdbc.Driver 5 6<!--引用外部属性文件,依赖context名称空间--> 7<!--classpath:应用类路径下资源--> 8<context:property-placeholder location="dbconfig.properties"></context:property-placeholder> 9<!--引用外部属性文件(spring管理连接池)--> 10<!-- ${key} 动态取出配置文件中键对应的值 --> 11<!--username 是spring中的关键字,key不能设为username--> 12<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 13 <property name="user" value="${user}"></property> 14 <property name="password" value="${password}"></property> 15 <property name="jdbcUrl" value="${jdbcUrl}"></property> 16 <property name="driverClass" value="${driverClass}"></property> 17</bean>

实验十三 | 基于XML的自动装配(自动赋值)

自动装配《仅对自定义类型的属性有效,基本类型无法赋值
autowire="default/no" 不自动装配,默认情况
autowire="byName" 按照名字寻找,以属性名作为id去容器中找到组件,并赋值。找不到则为null
autowire="byType" 以类型作为依据去容器中查找组件,若不唯一则产生错误。若没找到对应,装配null
autowire="constructor"
按构造器进行赋值
1)、先按照有参构造器的参数类型进行匹配(成功赋值),不成功则赋值null
2)、如果按照类型找到了多个;以参数名作为id进行匹配,找到赋值,找不到则赋值null
3)、不会产生报错

<bean id="person01" class="per.wzy.spring.Person" autowire="constructor"></bean>

实验十四 SPEL测试

  • 在SpEL中使用字面量

  • 引用其他bean

  • 引用其他bean的某个属性值

  • 调用静态方法 #{T(全类名).静态方法名}

  • 调用非静态方法

    <bean id="person03" class="per.wzy.spring.Person"> <!--使用字面量,运算符--> <property name="age" value="#{15*3}"></property> <!--引用其他bean的某个属性值--> <property name="name" value="#{person01.book.bookname}"></property> <!--引用其他bean--> <property name="book" value="#{book01}"></property> </bean>
    1<bean id="person02" class="per.wzy.spring.Person"> 2 <property name="book" value="#{book01}"></property> 3 <!--调用静态方法--> 4 <property name="name" value="#{T(java.util.UUID).randomUUID().toString()}"></property> 5 <!--调用非静态方法--> 6 <property name="age" value="#{person01.getAge()}"></property> 7</bean>

★实验十五 | 使用注解分别创建Dao,Service,Controller

某个类上添加上任何一个注解都能快速的将这个组件加入到ioc容器的管理中
Spring有四个注解
@Controller:控制器;我们推荐给控制器层(serv1et包下的这些)的组件加这个注解
@Service:业务逻辑;我们推荐业务逻辑层的组件添加这个注解; Bookservice
@Repository:给数据库层(持久化层,dao层)的组件添加这个注解
@Component:给不属于以上几层的组件添加这个注解

注解可以随意添加。spring底层不会验证该组件

步骤:

  1. 给要添加的组件上添加上述四个注解的一个

  2. 告诉Spring,自动扫描添加了注解的组件,依赖context名称空间

  3. 一定要导入aop包(支持注解模式)

    <!--context:component-scan 自动组件扫描--> <!--base-package 将基础包及其下所有包中添加了注解的类,自动添加到ioc容器-->

    <context:component-scan base-package="per.wzy"></context:component-scan>

使用注解加入到容器中的组件,和使用配置加入到容器中的组件行为都是默认一样的;
1、组件的id。默认就是组件的类名首字母小写
2、组件的作用域,默认就是单例的;

1public class SpringTest { 2 3 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext2.xml"); 4 5 @Test 6 public void test(){ 7 Object booksql = applicationContext.getBean("bookSql"); 8 Object booksql1 = applicationContext.getBean("bookSql"); 9 10 System.out.println(booksql==booksql1); //true 11 12}

注解后课添加(”XXX“)更改默认名称 || @Repository("bok")

添加Scope注解更改单/多实例 || @Scope(value = "prototype")

实验十六 | 指定扫描时不包含的类

1<context:component-scan base-package="per.wzy"> 2 <!--通过注解判断是否添加进容器,指定注解不添加包含此注解的类--> 3 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter> 4 <!--通过类指定不添加到容器中--> 5 <context:exclude-filter type="assignable" expression="per.wzy.service.BookService"></context:exclude-filter> 6 </context:component-scan>

实验十七 | 指定扫描时要包含的类

必须禁用默认的扫描规则

1 <context:component-scan base-package="per.wzy" use-default-filters="false"> 2 <!-- use-default-filters="false" 禁用默认的扫描规则--> 3 <context:include-filter type="assignable" expression="per.wzy.service.BookService"></context:include-filter> 4 </context:component-scan>

★实验十八 | 使用@Autowired注解实现根据类型的自动装配

bookSql.java

1@Repository 2public class bookSql { 3 4 public void bookSave(){ 5 System.out.println("svae book...."); 6 } 7}

BookService.java

1@Service 2public class BookService { 3 4 @Autowired 5 private bookSql bsql; //自动装配 6 7 public void bookAdd(){ 8 bsql.bookSave(); 9 } 10}

BookServlet.java

1@Controller 2public class BookServlet { 3 4 @Autowired 5 private BookService service; 6 7 public void get(){ 8 service.bookAdd(); 9 } 10}

测试方法

1public class SpringTest { 2 3 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext2.xml"); 4 5 @Test 6 public void test(){ 7 BookServlet bean = applicationContext.getBean(BookServlet.class); 8 bean.get(); 9 10 } 11}

输出:

svae book....

★实验十九 | 资源类型的bean不止一个,默认根据@Autowired注解标记的成员变量名作为id查找bean

@Autiwired 原理

  1. 先按照类型去容器中寻找对应的组件

  2. 找到一个,进行赋值

  3. 没有找到,抛出异常

  4. 找到多个,按照变量名作为id继续匹配。若没有对应匹配,报错

    • 原因(依据变量名进行匹配)
    • 解决:使用@Qualifier(value = "bookService")指定字符串作为id

    @Controller public class BookServlet {

    1@Qualifier(value = "bookService") 2@Autowired 3private BookService service2; 4 5public void get(){ 6 service2.bookAdd(); 7}

    }

★实验二十 | 使用@Qualifier注解明确指定目标bean的id

使用@Qualifier(value = "bookService")指定字符串作为id

1@Controller 2public class BookServlet { 3 4 @Qualifier(value = "bookService") 5 @Autowired 6 private BookService service2; 7 8 public void get(){ 9 service2.bookAdd(); 10 } 11}

★实验二十一 | 在方法的形参上使用@Qualifier注解

1/** 2 * 方法上有autowired注解 3 * 1.该方法会在bean创建时自动运行 4 * 2.这个方法上的每一个参数都会自动注入值 5 * @param service 6 * @param bookSqls 7 */ 8 @Autowired 9 public void limengkeShabi(BookService service, @Qualifier(value = "bookSql") bookSql bookSqls){ 10 System.out.println("BookService:"+service+" bookSql:"+bookSqls); 11 }

★实验二十二 | @Autowired注解的required属性指定某个属性允许不被设置

1@Controller 2public class BookServlet { 3 4 @Qualifier(value = "bookService") 5 @Autowired(required = false) 6 private BookService service3; 7 8 public void get(){ 9 System.out.println("services3....."+service3); 10// service3.bookAdd(); 11 } 12}

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

======

来自为知笔记(Wiz)

======

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )