Spring概述

  1. Spring是开源的轻量级框架
  2. Spring的两大核心思想
    1)AOP(面向切面编程)扩展功能模块时对源代码不进行修改来实现
    2)IOC(控制反转)获取对象不再使用我们以往的new,而是使用配置文件进行获取
  3. Spring是一站式的框架,在三层结构中每一层都有解决方案
    1)dao层:jdbcTemplate
    2)service层:Spring的IOC
    3)web层:SpringMVC

IOC底层原理

  1. 底层中主要使用到的技术
    1)xml
    2)dom4j
    3)工厂设计模式
    4)反射
  2. 文字描述
    1)首先创建好某个类,并且在配置文件中进行相应的配置。
    2)接着创建工厂类,使用dom4j对配置文件进行解析,得到类名的全路径
    3)采用反射机制,加载上面的类(forName),调用(newInstance)获得相应的类对象
  3. 图片描述(图片来源:传智播客)

IOC准备

  1. jar包(基础使用)
  2. 配置文件(名称位置没有要求,位置推荐src下,名称官方推荐applicationContext.xml)
    注:配置文件提示错误是ide的问题,本身没有错误
  3. 配置文件内容及约束(schema约束)
<?xml version="1.0" encoding="UTF-8"?>
<!-- schema约束 -->
<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">
	<!-- 内容 -->
</beans>        

IOC入门

  1. 创建类
class A{
	public void test(){
		System.out.println("this is a test");
	}
}
  1. 配置文件中配置
<?xml version="1.0" encoding="UTF-8"?>
<!-- schema约束 -->
<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">
	<!-- id:在测试类中根据id获取对象,值随意 class:必须是要获取某个类对象类的全路径 -->
	<bean id="a" class="tqb.ioc.test.A"></bean>
</beans>  
  1. 测试类
class Test{
	@Test
	public void test1(){
		//加载配置文件
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		//获取类对象,采用配置文件的id值
		A a = (A) context.getBean("a");
		// 调用具体的方法
		a.test();//this is a test
	}
}

Bean实例化的三种方式

  1. 采用无参数构造器实例化(就是IOC入门案例)
    注:当某个类中没有带参数的构造器时,即使类中没有写无参数的构造器,其实无参数的构造器是存在的(反编译可以看到)
  2. 使用静态工厂实例化
    1) 使用上边的A类
    2)创建静态工厂类
    3) 配置文件配置
    4) 测试类
class AFactory{
	public static A getA(){
		return new A();
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- schema约束 -->
<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">
	<!-- class:静态工厂类的全路径 factory-method:工厂类的获取对象的方法名称 -->
	<bean id="a1" class="tqb.ioc.test.AFactory" factory-method="getA"><bean>
</beans>  
class Test{
	@Test
	public void test1(){
		//加载配置文件
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		//获取类对象,采用配置文件的id值
		A a1 = (A) context.getBean("a1");
		// 调用具体的方法
		a1.test();//this is a test
	}
}
  1. 使用示例工厂实例化
    1)使用A类
    2)创建实例工厂
    3)配置文件
    4)测试
class AFactory1{
	public A getA(){
		return new A();
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- schema约束 -->
<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">
	<!-- class:静态工厂类的全路径 factory-method:工厂类的获取对象的方法名称 factory-bean:工厂类对应的id值 -->
	<bean id="aFactory" class="tqb.ioc.test.AFactory1"><bean>
	<bean id="a2" factory-bean="aFactory" factory-method="getA"></bean>
</beans>  
class Test{
	@Test
	public void test1(){
		//加载配置文件
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		//获取类对象,采用配置文件的id值
		A a2 = (A) context.getBean("a2");
		// 调用具体的方法
		a2.test();//this is a test
	}
}

bean标签常用属性(部分)

  1. id:案例
  2. class:案例
  3. name:和id同等作用,只不过可以使用一些特殊符号,如_ #等,id中不允许使用
  4. scope:有五个值
    1)singleton:单例模式(默认)
    2)prototype:多例模式
    3)request:将得到的对象放置到request域中
    4)session:将得到的对象放置到session域中
    5)globalSession:将得到的对象放置到globalSession中
  5. 测试(单例)
    注:给A类的配置文件中添加socpe属性,值为singleton
<bean id="a" class="tqb.ioc.test.A" scope="singleton"></bean>
public class Test {
	@Test
	public void fun(){
		//加载配置文件
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		//得到对象
		A a1 = (A) context.getBean("a");
		A a2 = (A) context.getBean("a");
		
		System.out.println(a1 == a2);//true scope="singleton" 单例模式(默认) 当scope="prototype",输出false
	}
}

属性注入

  1. 使用有参构造器注入属性
package tqb.ioc.test.construct;

public class User {
	
	private String username;
	
	public User(String username) {
		this.username = username;
	}

	public void test(){
		System.out.println(username);
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- schema约束 -->
<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="user1" class="tqb.ioc.test.construct.User">
	   		<constructor-arg name="username" value="zhangsan" ></constructor-arg>
	   </bean>
</beans>        
public class Test {
	@Test
	public void fun(){
		//加载配置文件
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
	
		User user1 = (User) context.getBean("user1");
		
		user1.test();//zhangsan
	}
}
  1. 使用set方法注入属性
package tqb.ioc.test.set;

public class User {
	private String name;

	public void setName(String name) {
		this.name = name;
	}
	
	public void test(){
		System.out.println(name);
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- schema约束 -->
<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">
	   <!-- 使用set方法进行注入属性 -->
	    <bean id="user2" class="tqb.ioc.test.set.User">
	    	<property name="name" value="lisi"></property>
	    </bean>
</beans>        
public class Test {
	@Test
	public void fun(){
		//加载配置文件
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
	
		User user2 = (User) context.getBean("user2");
		
		user2.test();//lisi
	}
}
  1. 注入对象类型属性
public class UserDao {
	public void fun(){
		System.out.println("dao......fun()");
	}
}
public class UserService {
	private UserDao userDao;
	
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	
	public void test(){
		userDao.fun();//dao......fun()
		System.out.println("service");//service
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- schema约束 -->
<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="tqb.ioc.test.object.UserDao"></bean>
	     <bean id="userService" class="tqb.ioc.test.object.UserService">
	     	<property name="userDao" ref="userDao"></property>
	     </bean>
</beans>        
public class Test {
	@Test
	public void fun(){
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserService userService = (UserService) context.getBean("userService");
		userService.test();
	}
}
  1. 注入复杂类型属性
    1)数组



    2)list集合


    3)map集合


IOC和DI的区别

  1. IOC(控制反转):把对象的创建交给Spring的配置文件
  2. DI(依赖注入):向类中的属性设置值
  3. 关系:DI不能单独存在,必须在IOC的基础之上