spring的IOC和DI的配置及总结
一 spring的 IOC
1.简单入门
-
先导入依赖坐标
<!--导入spring的context坐标,context依赖core、beans、expression--> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> </dependencies>
-
创建applicationContext.xml的配置文件
2.spring的bean对象实例化配置
-
无参构造方法创建
<bean id="" class=""></bean> id 名称 class 包路径
-
静态工厂创建
先创建一个静态工厂类
public class UserServiceStaticFactory { /** * 静态工厂方法 * @return */ public static UserService getBean(){ return new UserServiceImpl(); } }
<!-- 使用静态工厂创建bean,放入spring容器--> <bean id="userService" class="" factory-metgod = "getBeen"></bean>
-
普通工厂创建
创建一个普通工厂
public class UserServiceFactory { public UserService getBean(){ return new UserServiceImpl(); } }
<bean id="userServiceFactory" class=""></bean> <bean id="userService" factory-bean="" factory-metgod = "getBeen"></bean>
3.bean对象的作用范围
在bean声明时它有一个scope
属性,它是用于描述bean的作用域。
<bean id="" class="" scope=""></bean>
singleton: 单例 代表在SpringIOC容器中只有一个Bean实例 (默认的scope)
prototype:多例 每一次从Spring容器中获取时,都会返回一个新的实例
request 用在web开发中,将bean对象request.setAttribute()存储到request域中
session 用在web开发中,将bean对象session.setAttribute() 存储到session域中
4.bean对象的生命周期
单例对象 : scope="singleton"
一个应用只有一个对象的实例。它的作用范围就是整个引用。
生命周期:
- 创建:当应用加载,创建容器时,对象就被创建了。
- 活跃:只要容器在,对象一直活着。
- 销毁:当应用卸载,销毁容器时,对象就被销毁了。
多例对象 : scope="prototype"
每次访问对象时,都会重新创建对象实例。
生命周期:
- 创建:当使用对象时,创建新的对象实例。
- 活跃:只要对象在使用中,就一直活着。
- 销毁:当对象长时间不用时,被 java 的垃圾回收器回收了。
二 spring的DI
1.依赖注入的方式
(1) 有参构造注入
<!--配置bean对象,使用构造函数注入值-->
<bean id="user" class="">
<constructor-arg name="username" value="张三丰"></constructor-arg>
</bean>
类中需要提供一个对应参数列表的构造函数。
涉及的标签: constructor-arg
涉及的属性:
- name:指定参数在构造函数中的名称 用这个找给谁赋值
- value:它能赋的值是基本数据类型和String类型
- ref:它能赋的值是其他bean类型,也就是说,必须得是在配置文件中配置过的bean
构造注入优缺点:
- 优势 : 在获取bean对象时,数据注入是必须的,否则无法创建成功
- 缺点 : 改变了bean对象的实例化方式,使我们在创建对象时如果用不到某此数据同样也要提供。
(2) set方法注入
<!--配置bean对象,使用setter方法注入值-->
<bean id="user" class="">
<property name="username" value="张无忌"></property>
</bean>
调用对象属性的setter方法也可以为属性赋值
涉及的标签: property
涉及的属性:
- name:找的是类中set方法后面的部分
- ref:给属性赋值是其他bean类型的
- value:给属性赋值是基本数据类型和string类型的 实际开发中,此种方式用的较多
Set注入优缺点:
- 优势 : 创建对象时没有明确的限制,可以直接使用默认的无参构造函数
- 缺点 : 如果某个成员必须有值,获取对象时set方法可能没有执行
注意:此种方式赋值一定要有无参构造函数,并且为属性提供公有的getter和setter方法
为集合注入值
<!--为数组array注入值-->
<property name="myArray">
<array>
<value>数组1</value>
<value>数组2</value>
<value>数组3</value>
</array>
</property>
<!--为list注入值-->
<property name="myList">
<list>
<value>List1</value>
<value>List2</value>
<value>List3</value>
</list>
</property>
<!--为Set注入值-->
<property name="mySet">
<set>
<value>SET1</value>
<value>SET2</value>
<value>SET3</value>
</set>
</property>
<!--为map注入值
注意map为键/值对的形式
-->
<property name="myMap">
<map>
<entry key="map1" value="aaa"></entry>
<entry key="map2" value="bbb"></entry>
<entry key="map3" value="ccc"></entry>
</map>
</property>
<!--为Properties注入值-->
<property name="properties">
<props>
<prop key="prop1">AAA</prop>
<prop key="prop2">BBB</prop>
<prop key="prop3">CCC</prop>
</props>
</property>
</bean>
-
用于给list注入的子标签
array
、list
、set
-
用于给map注入的子标签
map
、props
三 ApplicationContext的继承体系
applicationContext:接口类型,代表应用上下文,可以通过其实例获得 Spring 容器中的 Bean 对象
四 ApplicationContext的实现类
- ClassPathXmlApplicationContext : 它是从类的根路径下加载配置文件 推荐使用这种
- FileSystemXmlApplicationContext : 它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
- AnnotationConfigApplicationContext: 当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。
五 getBean()方法的使用
public Object getBean(String name) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(name);
}
public <T> T getBean(Class<T> requiredType) throws BeansException { assertBeanFactoryActive();
return getBeanFactory().getBean(requiredType);
}
其中,当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回是Object,需要强转。
当参数的数据类型是Class类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,则此方法会报错
getBean()方法使用
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService1 = (UserService) applicationContext.getBean("userService");
UserService userService2 = applicationContext.getBean(UserService.class);
六 配置数据源
1.导入相关依赖
<!-- C3P0连接池 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
2.手动创建数据源
创建C3P0连接池
@Test
public void testC3P0() throws Exception {
//创建数据源
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//设置数据库连接参数
dataSource.setDriverClass("com.mysql.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUser("");
dataSource.setPassword("");
//获得连接对象
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
创建Druid连接池
@Test
public void testDruid() throws Exception {
//创建数据源
DruidDataSource dataSource = new DruidDataSource();
//设置数据库连接参数
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("");
dataSource.setPassword("");
//获得连接对象
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
③提取jdbc.properties配置文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=
jdbc.password=
④读取jdbc.properties配置文件创建连接池
@Test
public void testC3P0ByProperties() throws Exception {
//加载类路径下的jdbc.properties
ResourceBundle rb = ResourceBundle.getBundle("jdbc");
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(rb.getString("jdbc.driver"));
dataSource.setJdbcUrl(rb.getString("jdbc.url"));
dataSource.setUser(rb.getString("jdbc.username"));
dataSource.setPassword(rb.getString("jdbc.password"));
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
3.spring配置数据源
可以将DataSource的创建权交由Spring容器去完成
DataSource有无参构造方法,而Spring默认就是通过无参构造方法实例化对象的
DataSource要想使用需要通过set方法设置数据库连接信息,而Spring可以通过set方法进行字符串注入
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
<property name="user" value=""/>
<property name="password" value=""/>
</bean>
测试从容器当中获取数据源
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = (DataSource) applicationContext.getBean("dataSource");
Connection connection = dataSource.getConnection();
System.out.println(connection);
抽取jdbc配置文件
applicationContext.xml加载jdbc.properties配置文件获得连接信息。
<!--加载属性配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
ty-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>