zoukankan      html  css  js  c++  java
  • Spring框架——关于IOC容器和注解的36个小实验

    实验1:通过IOC容器创建对象,并为属性赋值★

    <bean id="page"  class="com.neuedu.Bean.Page">
    
    <property name="fontSize" value="大写"></property>
    
    <property name="fontNum" value="12"></property>
    
    </bean>
    
     
    
    ApplicationContext iocContainer = new ClassPathXmlApplicationContext("applicationContext.xml");
    
    Page bean2 = (Page)iocContainer.getBean("page");

    实验2:根据bean的类型从IOC容器中获取bean的实例★

    <bean id="page"  class="com.neuedu.Bean.Page">
    
    <property name="fontSize" value="大写"></property>
    
    <property name="fontNum" value="12"></property>
    
    </bean>
    
     
    
    ApplicationContext iocContainer = new ClassPathXmlApplicationContext("applicationContext.xml");
    
    Page bean2 = iocContainer.getBean(Page.class);
    

      

    实验3:通过构造器为bean的属性赋值

    <bean id="Book" class="com.neuedu.Bean.Book">
    
    <!-- 以下为给带参构造器传送参数 -->
    
    <constructor-arg value="123" ></constructor-arg>
    
    <constructor-arg value="456" ></constructor-arg>
    
    <constructor-arg value="789" ></constructor-arg>
    
    </bean>
    

      

    实验4:通过index属性指定参数的位置

    <bean id="Book" class="com.neuedu.Bean.Book">
    
    <property name="num" value="123"></property>
    
    <constructor-arg value="123" index="0"></constructor-arg>
    
    <constructor-arg value="123" index="1"></constructor-arg>
    
    <constructor-arg value="123" index="2"></constructor-arg>
    
    </bean>
    

      

    实验5:通过类型不同区分重载的构造器

    <bean id="page"  class="com.neuedu.Bean.Page">
    
    <constructor-arg value="123" type="int"></constructor-arg>
    
    <constructor-arg value="456" type="String"></constructor-arg>
    
    </bean>
    

      

    实验6:通过p名称空间为bean赋值

    <bean id="Book2"  parent="Book"
    
    p:num="254"
    
     />
    

      

    实验14:给bean的级联属性赋值

    <bean id="page"  class="com.neuedu.Bean.Page">
    
    <constructor-arg value="123" type="int"></constructor-arg>
    
    <constructor-arg value="456" type="String"></constructor-arg>
    
    </bean>
    
    <bean id="Book" class="com.neuedu.Bean.Book">
    
    <property name="page" ref="page"></property>
    
    </bean>
    

      

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

    <bean id="page" scope="prototype" class="com.neuedu.Bean.Page">
    
    <constructor-arg value="123" type="int"></constructor-arg>
    
    <constructor-arg value="456" type="String"></constructor-arg>
    
    </bean>
    

      

    Scope属性:

    Prototype:每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new XxxBean()的操作

    Request:每次Http请求都会创建一个新的Bean, 仅适用于WebApplication环境

    Session:每次创建一个session,创建对象,同一个Http Session共享一个Bean,不同的HttpSession使用不同的Bean。仅适用于WebApplication环境

    Singleton:Spring容器中仅存在一个Bean实例,Bean以单例的方式存在

    实验22:创建带有生命周期方法的bean

    <bean id="page" scope="singleton" class="com.neuedu.Bean.Page" init-method="int" destroy-method="destroy">
    
    <constructor-arg value="123" type="int"></constructor-arg>
    
    <constructor-arg value="456" type="String"></constructor-arg>
    
    </bean>
    

      

    实验20bean之间的依赖 depends-on="order"被依赖的对象会先创建

    <bean id="page" scope="singleton" class="com.neuedu.Bean.Page" depends-on="font">
    
    <constructor-arg value="123" type="int"></constructor-arg>
    
    <constructor-arg value="456" type="String"></constructor-arg>
    
    </bean>
    
    <bean id="font" class="com.neuedu.Bean.Font"></bean>
    

      

    实验18:通过继承实现bean配置信息的重用

    <bean id="Book"  class="com.neuedu.Bean.Book" 
    
    p:name="四大名著"
    
    p:num="258"
    
     />
    
     
    
     <bean id="Book2"  parent="Book"
    
    p:num="254"
    
     />
    

      

    实验19:通过abstract属性创建一个模板bean

    <bean id="Book"  abstract="true" class="com.neuedu.Bean.Book" 
    
    p:name="四大名著"
    
    p:num="258"
    
     />
    
     
    
     <bean id="Book2"  parent="Book"
    
    p:num="254"
    
     />
    

      

    实验7:测试使用null

    <bean id="page" scope="singleton" class="com.neuedu.Bean.Page" >
    
    <property name="fontSize">
    
    <null/>
    
    </property>
    
    </bean>
    

      

    null只有包装类和引用类型可以用

    实验8:引用其他bean

    <bean id="Book" class="com.neuedu.Bean.Book">
    
    <property name="page" ref="page"></property>
    
    </bean>
    

      

    实验9:引用内部bean

    <bean id="Book" class="com.neuedu.Bean.Book">
    
    <property name="page" >
    
    <bean id="page" scope="singleton" class="com.neuedu.Bean.Page" >
    
    <property name="fontSize" value="123"></property>
    
    </bean>
    
    </property>
    
    </bean>
    

      

    实验10:使用List类型的集合属性

    <bean id="pets" class="com.xgj.ioc.inject.construct.utilSchema.Pets"> <property name="petList" ref="petList" />
    
    </bean>
    
     
    
    <util:list id="petList" list-class="java.util.ArrayList" value-type="java.lang.String">
    
    <value>DOG</value>
    
    <value>CAT</value>
    
    <value>BIRD</value>
    
    </util:list>
    

      

    实验11:使用Map类型的集合属性

    <!-- 第一种写法 ,通过ref引用,此时需要在 uitl-map中声明id 推荐这种写法
    
    <bean id="pets" class="com.xgj.ioc.inject.construct.utilSchema.Pets"> <property name="petMap" ref="petMap" />
    
    </bean>
    
    <util:map id="petMap" map-class="java.util.HashMap">
    
    <entry key="101" value="dog" />
    
    <entry key="103" value="wolf" />
    
    <entry key="105" value="bird" />
    
    </util:map> --> 
    
     
    
    <!-- 第二种写法,嵌入内部 -->
    
    <bean id="pets" class="com.xgj.ioc.inject.construct.utilSchema.Pets"> <property name="petMap">
    
    <util:map map-class="java.util.HashMap">
    
    <!-- 可以通过map-class显示指定Map的实现类 -->
    
    <entry key="101" value="dog" />
    
    <entry key="103" value="wolf" />
    
    <entry key="105" value="bird" />
    
    </util:map>
    
    </property>
    
    </bean>
    

      

    实验12:使用prop子元素为Properties类型的属性赋值

    <bean id="pets" class="com.xgj.ioc.inject.construct.utilSchema.Pets"> <property name="petProperties" ref="petProperties" />
    
    </bean>
    
     
    
    <util:properties id="petProperties">
    
    <prop key="151">PIG</prop>
    
    <prop key="153">PINGUIN</prop>
    
    </util:properties>
    

      

    实验15:配置通过静态工厂方法创建的bean[通过静态方法提供实例对象,工厂类本身不需要实例化!]

    <bean id="staticFactory" class="com.neuedu.spring.bean.StaticFactory" factory-method="getBook">
    
    <constructor-arg value="book01"></constructor-arg>
    
    </bean>
    

      

    实验16:配置通过实例工厂方法创建的bean[通过实例方法提供实例对象,工厂类本身需要先创建对象!]

    <bean id="instanceFactory" class="com.neuedu.spring.bean.InstanceFactory"></bean>
    
    <bean id="bookFromInstanceFactory" factory-bean="instanceFactory" factory-method="getBook">
    
    <constructor-arg value="book02"></constructor-arg>
    
    </bean>
    

      

    实验17:配置FactoryBean

    public class MyFactoryBean implements FactoryBean<Book> {
    
     
    
    @Override
    
    public Book getObject() throws Exception {
    
    return new Book(22, "无字天书", "好啊", 22.5);
    
    }
    
     
    
    @Override
    
    public Class<?> getObjectType() {
    
    return Book.class;
    
    }
    
     
    
    @Override
    
    public boolean isSingleton() {
    
    return false;
    
    }
    
    }
    

      

    实验22[补充]:测试bean的后置处理器

    ①在bean的初始化方法调用前后执行操作的专门的对象

    ②自定义后置处理器实现该接口:org.springframework.beans.factory.config.BeanPostProcessor

    ③在springmvc中配置一下该bean对象.

    <bean class="com.neuedu.spring.bean.Book" init-method="init"></bean>
    
    <bean id="myBeanPostProcessor" class="com.neuedu.spring.bean.MyBeanPostProcessor"></bean>
    

      

    数据库连接池:

    6) 数据库连接池

    > 数据库连接池就是存放数据库连接(Connection)的集合

    > 我们获取一个数据库连接是一个相对很麻烦的过程,

    如果我们获取一个数据库连接,使用一次以后就给它关闭了

    下一次再去使用的时候就要重新创建一个新的数据库连接。

    > 所以我们提出了一个数据库连接池的概念,数据库连接池放的都是数据库连接(Connection

    我们在去使用数据库连接时候,不用再去重新创建数据库连接,而是直接从池中获取,

    使用完的数据库连接,也不是直接销毁,而是要放回到连接池。

    >

    数据库连接池的常见的属性:

    初始连接数量:数据连接池创建以后,保存数据库连接的数量[50]

    最小空闲连接数:数据库连接池最少得未使用的数据库连接的数量[10]

    最大空闲连接数:数据库连接池最大闲置连接数,当闲置连接数满了以后,将不会有其他连接进入池

    每次增加连接数:当数据库连接都被占用以后,一次性增加的数据库连接的个数[20]

    最大连接数:数据库连接池的最大容量,当最大连接数饱和了,则不再创建新的数据库连接[100]

    最大等待时间:当数据库连接池饱和以后,等待获取数据库连接的时间

    > 常见的数据库连接池

    - 所有的数据库连接池都需要实现DataSource,当使用数据库连接池是,我们便不再需要使用DriverManger获取数据库连接

    而是使用DataSource

     - Connection getConnection()

    - 从数据库连接池中获取数据库连接对象

    1.DBCP

    - DBCPApache出品的一款数据库连接

    - DBCP依赖于commons-pool

    - 使用DBCP需要导入两个jar包:

    commons-dbcp-1.4.jar

    commons-pool-1.5.5.jar

    - 当我们通过数据库连接池获取数据库连接以后,我们所获取到数据库连接已经不是我们熟悉的那个Connection

    数据库连接池对Connection对象进行了包装,它修改Connectionclose()方法,

    再去调用close()数据库连接将不会真的关闭,而是要放回到数据库连接池中,供其他线程使用。

    - 核心类:

    BasicDataSourceFactory

    2.C3P0(重点)

    - C3P0使用的是XML作为配置文件

    - 使用c3p0需要导入一个jar包:

    c3p0-0.9.1.2.jar

    - 导入c3p0的配置文件:

    1.配置文件的名字:c3p0-cofig.xml

    2.配置文件要求放到类路径下(src

    - 核心类:

    ComboPooledDataSource

    - 注意:

    DataSource就相当于池子,我们的数据库连接都是从DataSource中获取的,

    如果程序中有多个DataSource的实例,那么我们说你还不如不用数据库连接池。

    所以我们的DataSource在项目中应该只有一个实例。

    实验23:引用外部属性文件★

    jdbc.properties文件:

    jdbc.user=root

    jdbc.passowrd=123456

    jdbc.url=jdbc:mysql://localhost:3306/test

    jdbc.driver=com.mysql.jdbc.Driver

    <context:property-placeholder location="classpath:jdbc.properties"/>

    1.在目标属性上加@Value注解

    @Value("${jdbc.user}")

    private String username;

    2.

    <!-- 根据外部属性文件中的信息配置数据源 -->
    
    <bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    
    <property name="user" value="${jdbc.user}"></property>
    
    <property name="password" value="${jdbc.passowrd}"></property>
    
    <property name="jdbcUrl" value="${jdbc.url}"></property>
    
    <property name="driverClass" value="${jdbc.driver}"></property>
    
    </bean>
    
     
    
     
    
    ComboPooledDataSource bean = ioc.getBean(ComboPooledDataSource.class);
    
    Connection connection = bean.getConnection();
    
    System.out.println(connection);
    
    Statement st = connection.createStatement();
    
    ResultSet rs = st.executeQuery("select * from stu");
    
    while(rs.next()){
    
    String string = rs.getString("name");
    
    String string2 = rs.getString("school");
    
    System.out.println(string+"==="+string2);
    
    }
    

      

    实验24:基于XML的属性装配

    ①手动装配

    <!-- 属性的装配:手动装配 -->
    
    <bean id="userService" class="com.neuedu.spring.bean.UserService"></bean>
    
    <bean  id="userAction" class="com.neuedu.spring.bean.UserAction">
    
    <property name="userService" ref="userService"></property>
    
    </bean>
    

      

    ②自动装配

    <!-- 1.按类型装配:byType -->
    
    <!-- 首先检测当前bean中需要装配的属性的类型 -->
    
    <!-- 然后在IOC容器中查找匹配这个类型的bean -->
    
    <!-- 如果类型匹配的bean是唯一的,那么就将这个匹配的bean注入到userAction中 -->
    
     
    
    <bean id="userService" class="com.neuedu.spring.bean.UserService"></bean>
    
    <bean  id="userAction" autowire="byType" class="com.neuedu.spring.bean.UserAction"></bean>
    
     
    
    <!-- 2.按bean的id值装配:byName -->
    
    <!-- 首先检测当前bean中需要装配的属性的属性名,属性名是将setXxx()方法去掉set,首字母小写得到的 -->
    
    <!-- 然后根据属性名作为id的值,在IOC容器中查找对应的bean -->
    
    <!-- 如果能够找到,则将找到bean注入进去 -->
    

      

    6SpEL简介【见WORLD文档---了解】

    Spring Expression LanguageSpring表达式语言,简称SpEL。支持运行时查询并可以操作对象图。

    JSP页面上的EL表达式、Struts2中用到的OGNL表达式一样,SpEL根据JavaBean风格的getXxx()setXxx()方法定义的属性访问对象图,完全符合我们熟悉的操作习惯。

    6.1 基本语法

    SpEL使用#{}作为定界符,所有在大框号中的字符都将被认为是SpEL表达式。

    6.2 使用字面量

    ●整数:<property name="count" value="#{5}"/>

    ●小数:<property name="frequency" value="#{89.7}"/>

    ●科学计数法:<property name="capacity" value="#{1e4}"/>

    String类型的字面量可以使用单引号或者双引号作为字符串的定界符号

    <property name=namevalue="#{'Chuck'}"/>

    <property name='name' value='#{"Chuck"}'/>

    Boolean<property name="enabled" value="#{false}"/>

    实验25[SpEL测试I]SpEL中使用字面量

    实验26[SpEL测试II]SpEL中引用其他bean

    实验27[SpEL测试III]SpEL中引用其他bean的某个属性值

    实验28[SpEL测试IV]SpEL中调用非静态方法

    实验29[SpEL测试V]SpEL中调用静态方法

    实验30[SpEL测试VI]SpEL中使用运算符

    8.使用注解配置bean

    ①声明bean的注解

    @Component 将当前类声明为IOC容器中的一个普通的组件

    @Controller 将当前类声明为IOC容器中的一个控制器组件

    @Service 将当前类声明为IOC容器中的业务逻辑层组件

    @Repository 将当前类声明为IOC容器中的一个持久化层组件

    @ControllerAdvice

    Spring根据上述注解其实并不能分辨当前类是否真的是一个控制器或Dao,即使标记的类和注解不对应也没有语法错误。

    但在实际工作中,肯定要将专门的注解标记在对应的类上面。

    ②使用基于注解的bean的配置,需要额外导入一个jar包:spring-aop-4.0.0.RELEASE.jar

    ③需要设置自动扫描的包

    < context:component-scan base-package ="com.neuedu.ioc.bean"/>

    ④使用注解后,默认按照类名首字母小写作为id的值,也可以使用value属性指定idvalue属性名也可以省略注解

    注解 id值

    @Component                    

    public class CommonComponent {

    }

      commonComponent

    @Controller(value="neueduBookAction" )         

    public class BookAction {

    }

    neueduBookAction

    @Service("happyService" )                    

    public class BookService {

    }

     happyService

    实验31:通过注解分别创建DaoServiceController

    实验32:使用context:include-filter指定扫描包时要包含的类

    实验33:使用context:exclude-filter指定扫描包时不包含的类

    < context:component-scan base-package ="com.neuedu.ioc.bean"/>

    [1]base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包及其子包中的所有类。

    [2]当需要扫描多个包时可以使用逗号分隔,

    [3]如果仅希望扫描特定的类而非基包下的所有类,可使用resource-pattern属性过滤特定的类,示例:

    <context:component-scan base-package="com.neuedu.component" resource-pattern="autowire/*.class"/>

    [4]包含与排除

    <context:include-filter>子节点表示要包含的目标类

    注意:通常需要与use-default-filters属性配合使用才能够达到“仅包含某些组件”这样的效果。

    即:通过将use-default-filters属性设置为false,禁用默认过滤器,然后扫描的就只是include-filter中的规则

    指定的组件了。

    <context:exclude-filter>子节点表示要排除在外的目标类

    component-scan下可以拥有若干个include-filtejrexclude-filter子节

    ⑤使用注解进行自动装配:@Autowired注解[好处就是:连getset方法都不用写!]

    [1]首先检测标记了@Autowired注解的属性的类型

    [2]根据类型进行装配

    [3]如果指定类型的bean不止一个,那么根据需要被装配的属性的属性名做id的值,查找bean

    [4]如果根据id值还是没有找到bean,可以使用@Qualifier注解手动指定要装配的beanid.

    实验34:使用@Autowired注解实现根据类型实现自动装配★

    实验34[补充1]:如果资源类型的bean不止一个,默认根据@Autowired注解标记的成员变量名作为id查找bean,进行装配★

    实验34[补充2]:如果根据成员变量名作为id还是找不到bean,可以使用@Qualifier注解明确指定目标beanid

    实验36Autowired注解的required属性指定某个属性允许不被设置.

    实验37:在类上使用注解@Scope可以指定对象是单实例还是多实例的!

  • 相关阅读:
    LeetCode 260
    LeetCode 258
    LeetCode 237
    LeetCode 226
    LeetCode 203
    LeetCode 202
    codeforces 7D
    codefroces 7C
    codeforces 7B
    codeforces 6E (非原创)
  • 原文地址:https://www.cnblogs.com/Mr-zhaoz/p/7450070.html
Copyright © 2011-2022 走看看