控制反转IOC
IoC :Inverse of control 控制反转 ,思想就是在项目中引入一个工厂容器,对项目中接口依赖对象的创建,实现项目中对于依赖对象解耦合。
将程序中对象的创建权,交给工厂容器来管理
Spring其实就是一个工厂,出现为了解除程序中耦合,底层原理:工厂、配置文件、反射。程序不需要自己创建对象,获取spring工厂已经创建好的对象,对象创建权,反转到spring容器。
依赖注入DI
动态将某种依赖关系注入到对象之中。
例如: UserService中的UserDao变量 就可使用依赖注入
Bean的作用域
singleton单例 默认 一个IOC容器里只有一个对应的实例化对象
prototype多例
IOC容器在初始化时,会把容器中的所有单例Bean实例化, 默认调用无参构造,如果Bean设置了初始化方法init, 还会执行初始化方法, 在IOC容器关闭时, 单例Bean的销毁方法才会执行.
IOC容器配置 XML方法
配置文件 配置<bean标签> 必要属性 id class
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.hrh.a_quickstart.UserDaoImpl"/>
<bean id="userService" class="com.hrh.a_quickstart.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
<bean id="bean1" class="com.hrh.b_definition.Bean1"/>
<bean id="bean2" class="com.hrh.b_definition.Bean2Factory" factory-method="initBean2"/>
<bean id="bean3Factory" class="com.hrh.b_definition.Bean3Factory"/>
<bean id="bean3" factory-bean="bean3Factory" factory-method="createBean3"/>
<bean id="bean3_2" class="com.hrh.b_definition.MyFactoryBean"/>
<bean id="singleBean" class="com.hrh.c_scope.SingletonBean"/>
<bean id="prototypeBean" class="com.hrh.c_scope.PrototypeBean" scope="prototype"/>
<bean id="lifecycleBean" class="com.hrh.d_lifecycle.LifeCycleBeanImpl" init-method="init" destroy-method="destroy" scope="prototype"/>
<bean id="car" class="com.hrh.e_di.Car">
<constructor-arg index="0" value="保时捷"/>
<constructor-arg index="1" value="5000000"/>
</bean>
<!--<bean id="employee" class="com.hrh.e_di.Employee">
<property name="name" value="张三"/>
<property name="car" ref="car"/>
</bean>-->
<bean id="employee" class="com.hrh.e_di.Employee" p:name="李四" p:car-ref="car"/>
<bean id="collectionBean" class="com.hrh.e_di.CollectionBean">
<property name="list">
<list>
<value>abc</value>
<value>def</value>
</list>
</property>
<property name="set">
<set>
<value>1</value>
<value>1</value>
<value>2</value>
</set>
</property>
<property name="map">
<map>
<entry key="aa" value="11"/>
<entry key="bb" value="22"/>
</map>
</property>
<property name="properties">
<props>
<prop key="qwe">111</prop>
<prop key="ewq">222</prop>
</props>
</property>
</bean>
</beans>
IOC容器配置 注解方式
1 配置文件 扫描包及包后代类中所有有注解的类
2 类上添加注解 相当于XML的<bean>标签
3 @value 给变量注入值 相当于XML的<property>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.hrh"/>
</beans>
package com.hrh.b;
import org.springframework.stereotype.Repository;
@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Override
public void findByUsernameAndPassword() {
System.out.println("持久层 findByUsernameAndPassword ...");
}
}
package com.hrh.a;
import com.hrh.b.UserDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImpl implements UserService {
@Value("#{userDao}")
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
@Override
public void login() {
System.out.println("业务层 login ...");
userDao.findByUsernameAndPassword();
}
}
package com.hrh.a;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class test {
@Test
public void testBeanDefinition() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
UserService userService = (UserService) applicationContext
.getBean("userService");
userService.login();
}
}
Spring和Junit集成测试
在测试类中加入这两个注解 初始化容器 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext.xml")
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="userDao" class="com.hrh.test.UserDao"/>
<bean id="userService" class="com.hrh.test.UserService">
<property name="userDao" ref="userDao"/>
</bean>
</beans>
package com.hrh.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class test {
@Autowired
@Qualifier("userService")
private UserService userService;
@Test
public void test1(){
userService.login();
}
}
结合WEB代码
web.xml 配置信息
listener 监听器 监听容器的创建
全局配置信息 配置applicationContext.xml的的路径
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.hrh.web.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
</web-app>
WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
获取IOC容器
package com.hrh.web;
import com.hrh.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
UserService userService = ac.getBean("userService", UserService.class);
userService.login();
}
}