前言
先讲一下Spring的产生,因为之前的博客直接简单模拟了Spring,觉得比较唐突,毕竟有些人还不理解Spring用来干嘛,所以在这里详细讲解一下Spring
这是百度百科的解释,我就通俗的讲一下,Spring中有两个核心,一个是IOC(控制反转),一个是AOP(面向切面)
IOC(控制反转)
先说一个场景,比如我有一个类,这个类里面有个方法,而这个类是用于数据库持久层的,那就意味着如果工程需要我就要改变这个数据库持久层的实现方式,以前使用mysql,现在要用oracle,那么我就要改变这个类,同时改变使用这个类的类,说的有点迷糊,我用代码来讲吧:
User类
假如这个User类就是数据库持久层,此时用mysql实现,fun()代表对数据库的一大堆操作,假如由于数据库改为oracle,那么我就要写一个新的类用于数据库持久层,如果数据库持久层方式很多的话,就要很多的类,而且每改一次就要改变源代码,这绝对不符合我们JAVA的开闭原则
当然会有人说,我可以用接口实现,到时候传入一个接口的实现类就行了,这种方法的确比上面的好,但同样,它还是改变不了如果这个类要改变,你传入的实现类还是要改变,还是需要修改源码,也不符合开闭原则
那么还能改进,我可以不直接通过接口和实现类 new出来对象,我可以在接口和实现类中间增加一个工厂,所有的对象都从工厂中取得,这避免了在使用这个类的对象的时候,如果类改变对象也要改变的弊端,但是如果增加新类,工厂中就要增加新的get方法,来返回这个类的对象,这同样是不符合开闭原则
Spring呢,就是整合了以上的思路,它采用了在这里插入图片描述
这就是Spring IOC的底层实现思想,采用工厂模式+反射机制+配置文件,达到改变实现类的话,只需要改变配置文件,而不需要修改源码的目的,下面用简单的配置来实现一下
导入Spring的jar包
有个网址是:
http://repo.springsource.org/libs-release-local/org/springframework/spring
选择你需要版本的Spring jar包,然后在dist.zip中找到以下几个核心jar包,
导包就行了,
创建接口类和实现类
package com.mec.spring.core;
public interface IUser {
public void fun1();
}
public class User1 implements IUser {
@Override
public void fun1() {
System.out.println("User中的fun1方法执行");
}
}
XML配置
在src目录下建立一个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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
//前面为制式的配置,直接找到Spring的文档然后复制粘贴就好
<bean id = "iuser" class = "com.mec.spring.core.User1"></bean>
//这个bean就代表从工厂中取得一个bean,id可以为接口名,class为实现类带包名的类名
</beans>
测试类
public class Test {
public static void main(String[] args) {
//这个ApplicationContext可以理解为之前所说的Beanfactory
//ClassPathXmlApplicationContext表明用XML配置方式实现接口与类对应关系
ApplicationContext ap = new ClassPathXmlApplicationContext("Spring.config.xml");
//取出一个Bean
IUser iu = (IUser) ap.getBean("iuser");
//执行bean的方法
iu.fun1();
}
结果图
以上就是Spring的IOC,简单来说就是让Spring管理这些类,如果需要对象,导入配置文件后,直接从工厂中取出就行。
DI(依赖注入)
依赖注入的话,我在前面说过,就是说A中有B的依赖,B中有C的依赖,那么如果我们自己来做的话,在碰到依赖的话,就需要有一个set方法给依赖的对象赋值,如果需要很多的依赖,一个一个的赋值势必会很麻烦,那么我们可以把类交给Spring管理,对于其中对象的赋值,我们同样的可以直接通过配置的方式来完成,那么如果值改变,我们也只需要修改配置文件,避免修改源码,下面说一个具体的例子
假如我的类中需要一个String类型的依赖,那么以前的做法是给出set方法供外部设置值,而在Spring接管这个类后,我们只需要这样做
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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "iuser" class = "com.mec.spring.core.User1">
<property name = "name" value = "wangfei"/>
</bean>
</beans>
User:
public class User1 implements IUser {
private String do1;
@Override
public void fun1() {
System.out.println("User中的fun1方法执行"+do1);
}
public String getDo1() {
return do1;
}
public void setDo1(String do1) {
this.do1 = do1;
}
}
这里一定要给出get()和set()方法,网上有些教程不需要也可以执行,应该是版本问题,我用的4.3版Spring,建议在实现类给出get()和set()方法
结果: