IOC控制反转,降低代码之间的耦合度。把对象的创建交给spring来完成
实现方法 1.xml配置文件方式 2.注解方式
使用的技术:xml配置文件、dom4j解析xml文件、工厂设计模式、反射
实现原理
问题:Controller需要调用Service,不通过new(修改一个地方,需要找找找改改改)的方式怎么解决
public class DemoService(){
}
public class DemoController(){
//new DemoService()得到service么?
}
①创建xml配置文件,配置要创建的类
<bean id="demoService" class="com.pro1.service.DemoService"/>
②创建工厂类,使用dom4j解析xml配置文件,使用反射创建对象
pubic class demoFactory(){
public static DemoService getService(){
//使用dom4j解析xml文件
//根据id值得到对应的class属性
String classValue = "class属性值";
//使用反射创建类对象
Class clazz = Class.forName(classValue);
//创建类对象
DemoService demoService = clazz.newInstance();
return demoService;
}
}
则Controller中不需new
public class DemoController(){
demoFactory.getService();
}
bean的实例化三种方式(创建类)实际开发中只用第一种(默认的无参构造方法)
1.使用类的无参构造方法实例化
调用的就是类的无参构造方法
2.使用静态工厂创建(DmeoFactory.getBean())
<!-- 静态工厂创建类 -->
<bean id="getBeanStatic" class="com.idea.ioc.UserBeanFactory" factory-method="getBeanStatic"></bean>
//静态创建类工厂
public class UserBeanFactory {
public static User getBeanStatic() {
return new User();
}
}
public class TestIoc {
//测试类
@Test
public void testUserService() {
//加载spring配置文件
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
//得到配置文件中的对象
// User user = (User) context.getBean("userService");
User user = (User) context.getBean("getBeanStatic");
System.out.println(user);
user.add();
}
}
3.使用实例工厂创建(创建的不是静态方法,new DemoFactory().getBean()实例化)
bean标签的常用属性
①id属性 名称标识,不包含特殊符号,简洁明了
②class属性 需要创建对象类的全路径
③name属性 和id功能一样,但是name属性可以包含特殊符号(不怎么使用,针对Struts1框架)
④scope属性 (主要使用前两个)
singleton 默认值,单例 对象只创建一次
prototype 多例的 每一次创建都是创建新的对象
request web项目中,spring创建一个bean对象,将对象存入request域中
session web项目中,spring创建一个bean对象,将对象存入session域中
globalSession web项目中,应用在Prolet环境,如果没有Prolet环境那么相当于session,比如登录一次百度账号,贴吧、网盘等百度产品都不需要再次登录
属性注入之-注入对象类型属性
①创建service 、dao类(需要在service中得到dao对象)
②在service中定义一个dao类型属性(把dao对象做为属性类型)
③生成dao类型属性的方法
DI:依赖注入 向类中属性设置值(IOC为创建对象)
依赖注入不能单独存在,需要在IOC的基础上
spring整合web项目的基本原理
spring创建对象时需要加载xml文件,每次都需要new对象实现,效率很低,那么可以考虑将加载配置文件和创建对象过程在服务器启动时完成
//加载spring配置文件
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
(均已被spring封装,只需配置即可)
服务启动时,每个项目创建一个(servlet中)ServletContext对象,监听器可以监听到ServletContext对象什么时候创建,在此时加载配置文件并创建其中的对象,把创建出来的对象放在ServletContext域对象中(setAttribute()),获取对象时从ServletContext域对象中获取(getAttribute())
开启注解模式
引入jar包
<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"> <!-- bean definitions here -->
<!-- 开启注解扫描 属性为需要扫描的包位置 扫描配置路径下 类 方法 属性上面是否有注解
扫描多个包 1 分隔开com.idea.anno,com.idea.anno,....
2 写包含所有需要扫描的包的父路径 如:com.idea
-->
<context:component-scan base-package="com.idea.anno"></context:component-scan>
<!-- 只扫描属性上边的注解 -->
<!-- <context:annotation-config></context:annotation-config> -->
</beans>
在需要创建的类上添加
@Component(value="user") //同配置文件中<bean id="user" class=""/>
创建对象有四个注解
Spring中提供Component的三个衍生注解:(功能上目前是一样的…都是创建对象,为了让标注类本身的用途清晰和后续提供扩展)
@Controller //web层
@Service //业务层
@Repository //持久层