Web框架-Spring-SpringIOC
Spring的核心是什么
Spring核心内容:IOC
和AOP
。IoC (Inversion of Control,控制反转)
和 AOP(Aspect Oriented Programming,面向切面编程)
。
IOC
什么是IOC
控制反转(Inverse of Control,IOC),是一种降低对象之间耦合关系的设计思想。一般来说,在分层体系结构中,都是上层调用下层的接口,依赖注入最直接的体现,@AutoWired
,@Resource
这个注解。
注解@Autowired与@Resource,是如何实现依赖注入的
当某个Java对象(调用者)需要调用另一个Java对象(被依赖对象)的方法时,在传统模式下通常有两种做法:
- 原始做法: 调用者主动创建被依赖对象,然后再调用被依赖对象的方法。
- 简单工厂模式: 调用者先找到被依赖对象的工厂,然后主动通过工厂去获取被依赖对象,最后再调用被依赖对象的方法。
注意上面的主动二字,这必然会导致调用者与被依赖对象实现类的硬编码耦合,非常不利于项目升级的维护。使用 Spring框架之后,调用者无需主动获取被依赖对象,调用者只要被动接受 Spring容器为调用者的成员变量赋值即可,由此可见,使用 Spring后,调用者获取被依赖对象的方式由原来的主动获取,变成了被动接受——所以称之为控制反转。
另外从 Spring容器的角度来看, Spring容器负责将被依赖对象赋值给调用者的成员变量——相当于为调用者注入它依赖的实例,因此称之为依赖注入。依赖注入可以以向构造函数传递参数的方式发生,或者通过使用 setter 方法。
IOC优点:
- 1.通过IOC容器,开发人员不需要关注对象是怎么去创建的,同时增加新的类也比较方便了。
- 2.IOC容器可以通过配置文件来确定需要注入的实例化对象,因此很方便进行单元测试。
Spring下IOC容器和DI(依赖注入Dependency injection)
IOC容器:就是具有依赖注入功能的容器,是可以创建对象的容器,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给 Spring容器来做。在 Spring 中BeanFactory是IOC容器的实际代表者。
DI(依赖注入Dependency injection) :在容器创建对象后,处理对象的依赖关系。
依赖注入 Spring 的注入方式:
- Set方法注入方式
- 构造方法注入方式
- 静态工厂注入方式
- 基于注解的方式
1、Set方法注入方式:
控制层代码:创建一个pojo的car类:属性有汽车名字/地址
public class car implements Serializable {
private String name;
private Address address;
public car() {
}
public void setName(String name) {
this.name = name;
}
public void setAddress (Address address) {
this. address = address;
}
}
Spring配置XML文件:applicationContext.xml
。
<bean>
中的name
为类的一个别名,而class
为类的完整名称。给汽车名字/地址进行赋值。
<bean id="car" class="com.spring.service.pojo.car" >
<!--Set方式注入,-->
<property name="name" value="DB"></property>
<!—ref方式-->
<property name="address" ref="address"/>
</bean>
<!-- set注入 -->
<bean id="address" class="com.kuang.pojo.Address">
<property name="address" value="火之国:木叶村"/>
</bean>
2、构造器注入方式:
控制层代码:
public class car implements Serializable {
private String name;
private double price;
private String color;
public car(String name, double price ,String color) {
this.name = name;
this.color = color;
this.price = price;
}
}
Spring配置XML文件:applicationContext.xml
。
a. 索引注入,其中索引序号不能乱
在配置文件中,不再用<property>
标签,而是用<constructor-arg>
标签代替,:
<constructor-arg index="0" value="奥迪"></constructor-arg>
<constructor-arg index="1" value="500000"></constructor-arg>
<constructor-arg index="2" value="黑色"></constructor-arg>
b. 类型注入,其中类型顺序不能乱
<constructor-arg type="java.lang.String" value="奥迪" ></constructor-arg>
<constructor-arg type="java.lang.Double" value="500000"></constructor-arg>
<constructor-arg type="java.lang.String" value="黑色"></constructor-arg>
注意:属性中含有List,Array,Map
类型时:了解如下写法:
<constructor-arg index="3" >
<list>
<value>张三</value>
<value>李四</value>
<value>王五</value>
</list>
<map>
<entry key="id" value="1"></entry>
</map>
3、基于注解的方式(推荐使用,比较便捷少配置)
控制层代码:
@Autowired //@Resource
private OrderServiceImp orderService;
服务层代码:
@Service("orderService")
public class OrderServiceImp implements IOrderService {
@Autowired
private JavaOrderMDaoImp javaOrderMDao;
@Autowired
private JavaOrderDDaoImp javaOrderDDao;
@Override
public List<JavaOrderMList> findOrderM(OrderSearch search) {
return javaOrderMDao.findJavaOrderM(search);
}
@Override
public List<JavaOrderDList> findOrderD(OrderSearch search) {
return javaOrderDDao.findJavaOrderD(search);
}
}
DAO层代码:
@Repository("javaOrderMDao")
public class JavaOrderMDaoImp extends BaseHibernateDAO<JavaOrderM, Serializable> implements IJavaOrderMDao {...}
@Repository("javaOrderDDao")
public class JavaOrderDDaoImp extends BaseHibernateDAO<JavaOrderD, Serializable> implements IJavaOrderDDao {...}
注意点:
⑴ 持久层DAO层注解Repository中规定了名称,在Service层中声明名称必须一致。
⑵ 服务层Service层注解Service中规定了名称,在控制层中声明的名称必须一致。
⑶ 注解方式注入依赖注解:
- Ø @Component 把对象加入ioc容器,对象引用名称是类名,第一个字母小写
- Ø @Component(“name”) 把指定名称的对象,加入ioc容器
- Ø @Repository 主要用于标识加入容器的对象是一个持久层的组件(类)
- Ø @Service 主要用于标识加入容器的对象是一个业务逻辑层的组件
- Ø @Controller 主要用于标识加入容器的对象是一个控制层的组件
- Ø @Resource 注入属性(DI), 会从容器中找对象注入到@Resource修饰的对象上
- Ø @Autowired 注入属性(DI), 会从容器中找对象注入到@Autowired修饰的对象上
⑷ 注解可以简化配置,提升开发效率,但是也不利于后期维护。