IOC
IOC(Inversion of Control) 控制反转,将代码的控制权转移,从代码本身转移到spring容器中,由spring容器进行控制。
实现步骤:
- 获取spring容器
- 在容器中注册响应的bean
- 获取容器中已经注册的bean
DI
IO(Dependency Injection)依赖注入,当容器中的某一个bean对象需要外部另外一个bean对象的时候,我们不需要实例化这个对象,只要依赖容器注入就可以。
注入方式:
-
构造器注入
<!-- 注册userService --> <bean id="userService" class="com.service.UserServiceImpl"> <constructor-arg ref="userDaoJdbc"></constructor-arg> </bean> <!-- 注册jdbc实现的dao --> <bean id="userDao" class="com.dao.UserDaoImpl"></bean>
public class UserService implements IUserService { private IUserDao userDao; public UserService(IUserDao userDao) { this.userDao = userDao; } }
-
set属性注入
<bean id="userService" class="com.service.UserServiceImpl"> <property name="dao" ref="userDao"></property> </bean> <bean id="userDao" class="com.dao.UserDaoImpl"></bean>
public class UserServiceImpl implements IUserService{ private IUserDao dao; public void setDao(IUserDao dao) { this.dao = dao; } }
使用命名空间
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--用户service--> <bean id="userService" class="com.service.UserServiceImpl" p:dao-ref="userDao"></bean> <!--User DAO--> <bean id="userDao" class="com.dao.UserDaoImpl" p:qr-ref="query"></bean> <!--queryRunner--> <bean id="query" class="org.apache.commons.dbutils.QueryRunner"></bean>
-
接口注入(使用FactoryBean接口)
Spring工厂
- bean的创建不是由代码开发者去创建,转由spring容器去创建
- 创建好了之后用键值对的方式存在容器中 BeanFactory
- 拿到的BeanConfig getBean方法通过beanConfig中的className反射生成bean对象
获取Spring容器
-
通过源代码目录获取spring容器 ClassPathXmlApplicationContext 参数是…支持多配置
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
-
通过实际路径获取spring容器 FileSystemXmlApplicationContext 参数是…支持多配置
ApplicationContext ctx = new FileSystemXmlApplicationContext("E:/applicationContext.xml");
-
springmvc采用监听器自动创建存放在ServletContext中
web.xml<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--web容器启动后 监听到 立刻调用这个监听器 --> <!-- 1.获取spring容器 2.将容器存储到servletContext中 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 默认监听的位置是在WEB-INF/applicationContext.xml 监听器会监听 上下文中是否有 contextConfigLocation --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> </web-app>
//从web容器中获取spring容器 //1.通过servletContext中获取容器 //ApplicationContext ctx = (ApplicationContext) this.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); //2.使用工具类获取spring容器. WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
Spring装配bean
-
无参构造器装配(构造器与set属性注入常使用)
a.存在这个bean,并且这个bean一定要有无参的构造函数
b.在spring容器中配置这个bean,配置ID和class属性即可 -
静态工厂方法装配
<bean id="userService" class="com.service.UserServiceImpl"> <property name="dao" ref="staticUserDao"></property> </bean> <bean id="staticUserDao" class="com.entity.DaoFactory" factory-method="getStaticUserDaoImpl"></bean>
public class DaoFactory { //静态工厂 public static final IUserDao getStaticUserDaoImpl(){ return new StaticUserDaoImpl(); } }
-
动态工厂方法注入
<bean id="userService" class="com.service.UserServiceImpl"> <property name="dao" ref="userDao"></property> </bean> <bean id="userDao" class="com.dao.UserDao" factory-bean="daoFactory" factory-method="getUserDaoImpl"></bean> <bean id="daoFactory" class="com.entity.DaoFactory"></bean>
public class DaoFactory { //实例工厂 public IUserDao getUserDaoImpl(){ return new UserDaoImpl(); } }
-
FactoryBean方式(使用接口注入的装配方式)
<bean id="testBeanFactory" class="com.igeek.entity.TestBeanFactory"></bean>
public class TestBeanFactory implements FactoryBean<TestBean> { @Override public TestBean getObject() throws Exception { return new TestBean(); } @Override public Class<?> getObjectType() { return null; } @Override public boolean isSingleton() { return false; } }
bean作用域
在配置文件中设置bean的作用域 scope=“singleton”
-
singleton 单例模式 只有一个实例每次获取都是同一个(默认)
-
prototype 多例模式 每次获取都创建一个新的实例
bean生命周期
- init-method 指定bean的初始化方法
- destroy-method 指定bean的销毁方法
执行销毁
- 只有单例的才能手动销毁
- 主动销毁容器才能执行销毁方法
特殊类型注入
- list set map properties spring自带4个标签支持 list set map props
list set 子标签是value,map子标签entry(key value),props子标签是prop(key,值写在标签中) - 注入其他类的属性 spEl表达式 #{}
多配置文件开发
- 获取容器的时候参数采用数组的方式,有几个配置文件,就传入几个参数
- 在一个总配置文件中引入其他的配置文件