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>

  

实验20:bean之间的依赖 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

- DBCP是Apache出品的一款数据库连接

- DBCP依赖于commons-pool

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

commons-dbcp-1.4.jar

commons-pool-1.5.5.jar

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

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

再去调用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注入进去 -->

  

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

Spring Expression Language,Spring表达式语言,简称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=“name” value="#{‘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属性指定id,value属性名也可以省略注解

注解 id值

@Component

public class CommonComponent {

}

  commonComponent

@Controller(value="neueduBookAction" )

public class BookAction {

}

neueduBookAction

@Service("happyService" )

public class BookService {

}

 happyService

实验31:通过注解分别创建Dao、Service、Controller★

实验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-filtejr和exclude-filter子节

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

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

[2]根据类型进行装配

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

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

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

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

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

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

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

时间: 2024-08-29 06:12:30

Spring框架——关于IOC容器和注解的36个小实验的相关文章

Spring框架 之IOC容器 和AOP详解

主要分析点: 一.Spring开源框架的简介  二.Spring下IOC容器和DI(依赖注入Dependency injection) 三.Spring下面向切面编程(AOP)和事务管理配置  一.Spring开源框架的简介  Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来.它是为了解决企业应用开

Spring框架学习[IoC容器高级特性]

1.通过前面4篇文章对Spring IoC容器的源码分析,我们已经基本上了解了Spring IoC容器对Bean定义资源的定位.读入和解析过程,同时也清楚了当用户通过getBean方法向IoC容器获取被管理的Bean时,IoC容器对Bean进行的初始化和依赖注入过程,这些是Spring IoC容器的基本功能特性.Spring IoC容器还有一些高级特性,如使用lazy-init属性对Bean预初始化.FactoryBean产生或者修饰Bean对象的生成.IoC容器初始化Bean过程中使用Bean

好程序员Java干货分享Spring框架之IOC原理

好程序员Java干货分享Spring框架之IOC原理,前言:Spring框架是我们进行企业级开发的最常用框架,本章我们将了解Spring框架,并学习Spring的IOC特性以及IOC的实现原理:注解和反射. Spring框架简介 Spring是一种轻量级的控制反转(IOC)和面向切面编程(AOP)的容器框架,能够为企业级开发提供一站式服务. Spring的优点有 1.方便解耦,简化开发 通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度

Spring 总览及 IOC 容器的使用 —— Spring 官方文档解读(一)

Spring 总览及 IOC 容器的使用 -- Spring 官方文档解读(一) 什么是 Spring? spring 这个词在不同情况下有不同意义.可以指 Spring 框架本身,但更多地被用来表示 Spring 整个家族的产品. 设计理念 学习框架必须要知道它的设计理念,Spring 框架有着以下的理念: Spring 让你在架构种的各个层面有更多的选择,并且允许你尽晚的做出决策.比如,你在项目完成后可以通过更改配置来切换持久层的提供者. Spring 具有强大的灵活性,它不在意你是如何完成

Spring技术内幕——Spring Framework的IOC容器实现(一)

一.SpringIOC容器概述 IOC容器和依赖反转的模式 在面向对象的系统中,对象封装了数据和对数据的处理,对象的依赖关系常常体现在对数据和方法的依赖上.这些依赖关系可以通过把对象的依赖注入交给框架IOC容器来完成.他可以再解耦代码的同时提高了代码的可测试性. 依赖控制反转的实现由很多种方式,在Spring中,IOC容器是实现这个模式的载体,他可以再对象生成或者初始化时直接将数据注入到对象中,也可以通过将对象引用注入到对象数据域中的方式来注入对方法调用的依赖.这种依赖注入是可以递归的,对象被逐

看完这篇你还敢说,不懂Spring中的IoC容器?

一. 什么是IoC 什么是耦合和内聚 耦合指的就是模块之间的依赖关系.模块间的依赖越多,则表示耦合度越高,相应的维护成本就越高.内聚指的是模块内功能之间的联系.模块内功能的联系越紧密,则表示内聚度越高,模块的职责也就越单一.所以在程序开发中应该尽量的降低耦合,提高内聚.也就是设计原则中的开闭原则和单一职责原则. 工厂模式 工厂模式就是用来解决程序间耦合的一种设计模式.可以把所有要创建的对象放在工厂的一个集合里,当需要使用这个对象的时候,直接从工厂里面取出来用就行. 工厂模式的优点: 一个调用者想

spring框架学习(五)注解

spring框架学习(五)注解 注解Annotation,是一种类似注释的机制,在代码中添加注解可以在之后某时间使用这些信息.跟注释不同的是,注释是给我们看的,java虚拟机不会编译,注解也是不编译的,但是我们可以通过反射机制去读取注解中的信息.注解使用关键字@interface,继承java.lang.annotition.Annotition spring框架为我们提供了注解功能. 使用注解编程,主要是为了替代xml文件,使开发更加快速.但是,xml文件的使用就是解决修改程序修改源代码,现在

使用Spring.NET的IoC容器

使用Spring.NET的IoC容器 0. 辅助类库 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SpringDemo.Pub { public static class Pub { public static string ServiceNameA = "SpringDemo.Lib.Oracle.OracleDatabase"; pub

比Spring简单的IoC容器

比Spring简单的IoC容器 Spring 虽然比起EJB轻量了许多,但是因为它需要兼容许多不同的类库,导致现在Spring还是相当的庞大的,动不动就上40MB的jar包, 而且想要理解Spring的内部运行机制,阅读它的代码非常重要, 但是往往它的代码非常的"多". 现在根据Spring对Bean的生命周期的处理, 编写出一款非常小的IoC容器, 没有了对XML的解析,而是通过对Config对象的构造而完成IoC配置文件的声明, 相比较XML的方式, 对重构软件非常具有好处, 并且