一、IOC容器介绍
就是具有依赖注入功能的容器,是可以创建对象的容器,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。
【1】搭建Spring IOC容器需要的开发环境
①导入jar包
②创建Spring配置文件[Spring bean Configuration File]一般命名为applicationContext.xml
二、IOC容器细节
【0】IOC容器在Spring中的实现
IOC容器的两种实现方式:
(1)BeanFactory:IOC容器的基本实现,是Spring内部的基础设施,是面向Spring本身
(2)ApplicationContext:BeanFactory的子接口,提供了更多高级特性
ApplicationContext的主要实现类
ClassPathXmlApplicationContext:对应类路径下的XML格式的配置文件
FileSystemXmlApplicationContext:对应文件系统中的XML格式的配置文件
【1】通过IOC容器创建对象
<!-- 需要由IOC容器创建对象的全类名 -->
<!-- 为了便于从IOC容器中获取book对象,声明一个一个唯一的id值 -->
<bean id="book01" class="com.neuedu.spring.bean.Book">
<property name="bookId" value="2001"></property>
<property name="bookName" value="三国演义"></property>
</bean>
@Test
public void test01() {
//1.创建IOC容器自身的对象
//指定配置文件以类路径为基准的配置文件名
ApplicationContext ioc= new ClassPathXmlApplicationContext("bean.xml");
//2.从IOC容器中获取指定的对象
Object bean = ioc.getBean("book01");
System.out.println(bean);
}
注意:
①IOC容器本身对象创建时,会将配置文件中配置好的bean先创建出来
【2】给bean的属性赋值
①通过bean的property调用类的set方法
②通过bean的构造器赋值
<bean id="book" class="com.neuedu.spring.bean.Book" >
<constructor-arg value= "10010"/>
<constructor-arg value= "Book01"/>
<constructor-arg value= "Author01"/>
constructor-arg value= "20.2"/>
调用Book类的构造方法
③通过索引值指定参数位置(index)
④通过类型不同区分重载的构造器(type)
⑤给bean的级联属性赋值
⑥p名称空间
<bean id="studentSuper" class="com.neuedu.helloworld.bean.Student" p:studentId="2002" p:stuName="Jerry2016" p:age="18" />
【3】ioc容器中bean对象创建的时机
【4】bean之间的依赖
【5】通过继承实现bean配置信息重用
【6】通过abstract属性创建模板bean
【7】引用其它bean
<bean id="shop" class="com.neuedu.spring.bean.Shop" >
<property name= "categoryList">
<!-- 以字面量为值的List集合 -->
<list>
<value> 历史</value >
<value> 军事</value >
</list>
</property>
<property name= "bookList">
<!-- 以bean的引用为值的List集合 -->
<list>
<ref bean= "book01"/>
<ref bean= "book02"/>
</list>
</property>
</bean >
【9】使用map集合属性
<bean id="cup" class="com.neuedu.spring.bean.Cup">
<property name="bookMap">
<map>
<entry>
<key>
<value>bookKey01</value>
</key>
<ref bean="book01"/>
</entry>
<entry>
<key>
<value>bookKey02</value>
</key>
<ref bean="book02"/>
</entry>
</map>
</property>
</bean>
【10】配置通过静态工厂方法创建的bean[通过静态方法提供实例对象,工厂类本身不需要实例化!]
<bean id="staticFactory" class="com.neuedu.spring.bean.StaticFactory" factory-method="getBook">
<constructor-arg value="book01"></constructor-arg>
</bean>
只要在class类中有factory-method对应的静态方法
【11】配置通过实例工厂方法创建的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>
【12】工厂bean配置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;
}
}
【13】bean的后置处理器
—添加bean后置处理器后bean的生命周期
[1]通过构造器或工厂方法创建bean实例
[2]为bean的属性设置值和对其他bean的引用
[3]将bean实例传递给bean后置处理器的postProcessBeforeInitialization()方法
[4]调用bean的初始化方法
[5]将bean实例传递给bean后置处理器的postProcessAfterInitialization()方法
[6]bean可以使用了
[7]当容器关闭时调用bean的销毁方法
三、C3P0数据库连接池
【1】连接池解释
> 我们获取一个数据库连接是一个相对很麻烦的过程,
如果我们获取一个数据库连接,使用一次以后就给它关闭了
下一次再去使用的时候就要重新创建一个新的数据库连接。
> 所以我们提出了一个数据库连接池的概念,数据库连接池放的都是数据库连接(Connection)
我们在去使用数据库连接时候,不用再去重新创建数据库连接,而是直接从池中获取,
使用完的数据库连接,也不是直接销毁,而是要放回到连接池。
【2】引用外部属性文件
//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"/>
<!-- 根据外部属性文件中的信息配置数据源 -->
<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);
}
四、注解配置bean、XML属性装配
【1】基于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注入进去 -->
【2】注解配置bean
@Component 将当前类声明为IOC容器中的一个普通的组件
< context:component-scan base-package ="com.neuedu.ioc.bean"/>
④使用注解后,默认按照类名首字母小写作为id的值,也可以使用value属性指定id