注:本文于个人观点,如有错误欢迎纠正
一 名词解析:
1.IOC是一种"控制反转"思想
以前在程序中需要创建对象时,都是我们自己手动去new出来,这样非常麻烦,不利于对象管理。况且代码讲究低耦合(耦合:就是单元代码的紧密程度,一个单元代码的改动对另一个单元代码的影响),于是采用ioc思想,将对象创建、维护、销毁的控制权利交个了spring容器。
2.DI是依赖注入,是IOC的一种重要实现
一个对象的创建可能涉及到另一个对象的创建,比如A对象的成员变量持有B对象的引用,这就是依赖,A依赖于B,那么spring容器在创建对象A的时候,也会创建对象B,并把对象B注入到对象A中。
二 案例讲解:
采用一个例子来讲解下它的原理:
1.先引入spring所需的jar包,如果是maven则直接在pom.xml配置,否则手动添加jar包
2.创建一个DAO层接口,比如UserDao:
public interface userDao{
void addUser();
}
3.实现UserDao接口,生成UserDaoImpl:
public class UserDaoImpl implements UserDao{
void addUser(){
System.out.println("这是DAO层的具体实现-addUser方法的具体实现");
}
}
4.创建一个UserServicw接口,抽象方法do(),创建UserServiceImpl实现它:
public class UserServiceImpl implement UserService{
//依赖注入的对象
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
public void do(){
System.out.println("业务层的具体实现")
userDao.addUser();
}
}
5.xml配置文件:spring-ico.xml
<beans xmlns="http://www.springframework.org/schema/beans"
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
">
<!-- 声明userDao对象,交给spring创建 -->
<!--声明bean名称时可以用name、id,id唯一,name可以有多个-->
<bean name="userDao" class="com.yc.dao.impl.AccountDaoImpl"/>
<!-- 声明userService对象,交给spring创建 -->
<bean name="userService" class="com.yc.service.impl.AccountServiceImpl">
<!-- 注入userDao对象,需要set方法 对象引用用ref,这就是依赖注入-->
<property name="userDao" ref="userDao"/>
</bean>
</beans>
6.测试:
@Test
public void testByXml() throws Exception {
//加载配置文件
ApplicationContext applicationContext=
newClassPathXmlApplicationContext("spring/spring-ioc.xml");
UserService userService= (UserService) applicationContext.getBean("userService");
userService.do();
}
7:运行结果:
业务层的具体实现
这是DAO层的具体实现-addUser方法的具体实现
8.分析:
-
第一步生成工厂对象。加载完指定路径下 bean 配置文件后,利用框架提供的classpathXmlApplicationContext API 去生成工厂 bean。ClasspathXmlApplicationContext 负责生成和初始化所有的对象,比如,所有在 XML bean 配置文件中的 bean。
- 第二步利用第一步生成的上下文中的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean 名称 来返回一个真正的对象。一旦得到这个对象,就可以利用这个对象来调用任何方法。
三.Spring容器的依赖注入(基于xml配置和注解)
注入依赖有两种方式:一种是手动装配(分为两种:xml配置、注解(@Resource默认按名称注入;@AutoWired默认按类型,如果要按名称的话通常搭配@Qualifier)),另一种是自动装配(自动装配分三种:按名称、按类型、构造方法)
对象依赖注入的四种方法(xml配置):
1.set注入
<bean id="userDao" class="com.yc.dao.Impl"></bean>
<bean id=userService" class="com.yc.service.impl">
<!--实现类需要有依赖对象的参数的set方法-->
<property name="userDao ref="userDao"/>
</bean>
2.构造方法注入
<bean id="userDao" class="com.yc.dao.impl"></bean>
<bean id="userService" class="com.yc.service.impl">
<!--实现类需要有依赖对象的参数的构造方法-->
<!--constuctor节点有四个属性:index(当构造方法参数有两个以上,传值得时候index代表索引从0开始)、type(参数的类型)、ref(注入依赖对象)、value(值)-->
<constructor-arg ref="userDao"/>
</bean>
3.静态工厂方法和实例工厂
3.1 bean对象
class User{
private String name;
private int age;
public void setName(String name){
this.name=name;
}
public void setAge(int age){
this.age=age;
}
}
3.2 工厂类:
public class Factory{
public static User add(){
User user=new User();
user.setName=("张三");
user.setAge(18);
}
public User add2(){
User user=new User();
user.setName=("李四");
user.setAge(20);
}
}
3.3 xml配置为:
<!-- 静态工厂创建,调用静态方法add-->
<bean id="user1" class="com.yc.Factory"
factory-method="add"/>
<!-- 工厂实例创建,先创建工厂类在调用方法add2-->
<bean id="factory" class="com.yc.Factory" />
<bean id="user2" factory-bean="factory" factory-method="add2"/>
4 bean对象基于注解扫描
从上面知道,spring容器负责控制创建对象,我们要做的是在xml配置文件中申明需要创建的对象,但是当需要创建对象特别多的时候,可能会特别复杂。以此使用注解会非常方便:@Repository(申明DAO层的实现层)、@Service(申明业务层的实现层)、@Controller(控制层) 、@Component;最后需要我们在xml配置文件中加入包扫描,就是扫描这些注解所在的位置。
<!-- 声明包扫描 -->
<context:component-scan base-package="com.yc" />