文章目录
Spring
前言
Spring图解
1、概述
- Spring是轻量级的开源的J2EE框架(轻量级、开源、J2EE)
- Spring的两个核心部分:IOC和AOP
- IOC:控制反转,就是把创建对象的过程交给Spring进行管理
- AOP:面向切面,不修改源代码的情况下进行功能增强
- Spring特点
- 方便解耦,简化开发
- AOP编程的支持
- 方便和其他框架进行整合
- 方便进行事务操作
总结:Spring就是一个开源的,轻量级的ioc(控制反转)与aop(面向切面编程)框架。
1.2.1、下载Spring
- https://spring.io
官网下载地址:https://repo.spring.io/ui/repos/tree/General/release%2Forg%2Fspringframework%2Fspring
1.2.2、使用IDEA创建Java工程
- 创建工程
- 导入相关Jar包
注:Spring4应导入日志JAR包Spring5后不需要
创建测试:
(1)bean1.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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">
<!--id:名字唯 class:类的全路径 默认调用无参构造器一-->
<bean id="person1" class="com.ugrow.pojo.Person">
<property name="username" value="张三"/>
<property name="age" value="30"/>
</bean>
<bean id="person2" class="com.ugrow.pojo.Person">
<constructor-arg name="username" value="李四"/>
<constructor-arg name="age" value="20"/>
</bean>
<bean id="person3" class="com.ugrow.pojo.Person">
<constructor-arg name="username" value="赵武"/>
</bean>
<bean id="person4" class="com.ugrow.pojo.Person" p:username="赵四" p:age="30">
</bean>
</beans>
(2)测试:
public class SpringTest {
public static void main(String[] args) {
test1();
}
public static void test1(){
//加载配置文件获取IOC容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("bean1.xml");
//从容器中获取配置的对象
//Person person1 = ioc.getBean("person1",Person.class);
// Person person2 = ioc.getBean("person2",Person.class);
//System.out.println(person1.username);
// System.out.println("username: " + person2.username + "age:" + person2.age);
//BeanFactory xmlBeanFactory = new XmlBeanFactory("bean1.xml");
Person person3 = ioc.getBean("person3", Person.class);
System.out.println("username: " + person3.username + ",age: " + person3.age);
Person person4 = ioc.getBean("person4", Person.class);
System.out.println("username: " + person4.username + ",age: " + person4.age);
}
}
2、IOC容器
- IOC底层原理
- IOC接口
- IOC操作Bean管理
- IOC操作Bean管理(基于注解)
2.1 IOC(概念和原理)
2.1.1、什么是IOC
控制反转,把对象创建和对象之间的调用过程,交给Spring管理
使用IOC目的:为了降低耦合度
2.1.2、 IOC底层原理
- xml解析、工厂模式、反射
当我们底层调用程序,会是一一对应的关系,牵一发而动全身,那么我们想要解决这种弊端,怎么解决呢?加一层,使用工厂模式就可以解决啦!
- IOC过程
<bean id="person1" class="com.ugrow.pojo.Person">
public class FactoryDao { public static PersonDao factoryDaoMethod(String beanName) throws Exception { /*PersonDao personDao = new PersonDao(); return personDao;*/ Class aClass = Class.forName("beanName"); return (PersonDao) aClass.newInstance(); } }
2.2 IOC(BeanFactory接口)
Spring提供IOC容器的两种实现方式
BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供给开发人员使用
加载配置文件的时候不会创建对象,在使用对象才去创建对象
- ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般提供
给开发人员使用,加载配置文件的时候就会把配置文件中的对象进行创建
2.3、IOC操作Bean管理(基于xml方式)
上面写过
在bean标签有很多属性,介绍常用的属性
id属性:唯一的标识
class属性:类的全路径(包类路径)
name属性:同id,但可以加特殊符号(“/”)
创建对象的时候,默认也是执行无参构造方法完成对象创建
2.3.1、注入属性
DI:依赖注入,就是注入属性
(1) 第一种注入方式,使用set方法进行注入
- 创建类,定义属性和对应set方法
public class Person { public String username; public Integer age; public Person(){ System.out.println("person()构造器!"); } public Person(String username, Integer age) { this.username = username; this.age = age; System.out.println("有参构造!"); } public Person(String username) { this.username = username; } public void setUsername(String username) { System.out.println("setUsername()被调用了!"); this.username = username; } public void setAge(Integer age) { System.out.println("setAge()被调用了!"); this.age = age; } }
- 在Spring配置文件中配置对象创建,配置属性注入
-
在Spring配置文件中配置有参构造的标签(name省略,且没index时,必须按照形参顺序配
置)
<!--Spring实例化对象--> <bean id="person1" class="com.ugrow.pojo.Person">
<!--有参构造方法注入属性-->
<constructor-arg name="username" value="李四"/>
<constructor-arg name="age" value="20"/>
<!-- 索引值注入
<constructor-arg index="1" value="123"></constructor-arg>-->
</bean>
2.4、IOC操作Bean管理(基于xml注入其他类型属性)
2.4.1、字面量
<!--注入其他类型的属性-->
<bean id="user" class="com.yg.pojo.User">
<!--注入null值-->
<property name="username">
<null/>
</property>
<property name="password" value="123"></property>
<!--注入特殊字符,采用转义的方式-->
<!-- <property name="username" value="<李四>"></property>-->
<!--注入特殊字符,采用<![CDATA[]]>的方式-->
<property name="username">
<value><![CDATA[<<李四>>]]></value>
</property>
</bean>
2.4.2、注入属性
<!--外部注入-->
<bean id="emp3" class="com.ugrow.pojo.Employee">
<property name="deptment" ref="dept"/>
</bean>
<bean id="dept" class="com.ugrow.pojo.Deptment">
<property name="id" value="1"/>
<property name="deptName" value="财务部"/>
</bean>
<!--内部注入-->
<bean id="emp4" class="com.ugrow.pojo.Employee">
<property name="deptment">
<bean id="dept1" class="com.ugrow.pojo.Deptment">
<property name="id" value="2"/>
<property name="deptName" value="测试部"/>
</bean>
</property>
</bean>
<!--级联注入 加入get方法-->
<bean id="emp5" class="com.ugrow.pojo.Employee">
<property name="deptment" ref="dept3"></property>
<property name="deptment.id" value="3"></property>
<property name="deptment.deptName" value="什么部"></property>
</bean>
<bean id="dept3" class="com.ugrow.pojo.Deptment"></bean>
bean之间的依赖,改变创建顺序
<!--原来是按照配置的顺序创建bean--> <!--改变bean的创建顺序-->
<bean id="book" class="com.yg.pojo.Book"></bean>
<bean id="car" class="com.yg.pojo.Car" depends-on="person,book"></bean>
<bean id="person" class="com.yg.pojo.Person"></bean>
2.5、普通bean和工厂bean
普通Bean:配置文件定义bean类型就是返回值类型
工厂Bean:配置文件定义bean类型可以和返回类型不一样
在某些情况下,实例化bean过程比较复杂,数据过多时,要大量的配置信息,灵活性是受限的,Spring为此提供了一个org.Springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化bean的逻辑。通过实现该返回getObject 方法生成的对远程服务调用的代理。FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式
public class MyBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
Employee employee = new Employee();
employee.empName = "张三";
employee.id = 1;
employee.isBoss = false;
employee.list = new ArrayList();
return employee;
}
//返回创建对象的类型,Spring自动调用确认创建对象的类型
@Override
public Class<?> getObjectType() {
return Employee.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
- 在Spring配置文件中进行配置
<!--工厂Bean-->
<bean id="mybean" class="com.ugrow.pojo.MyBean"/>
2.6、IOC操作Bean管理(Bean作用域)
单实例:只有一个实例对象【new *()】-- 堆中的地址是同一个
多实例:有多个实例对象 – 堆中的地址不是同一个
在Spring里面,默认情况下,bean是单实例对象(只给我们new一次)
<!--默认情况单例 singleton:单例 prototype:多例-->
<bean id="person" class="com.ugrow.pojo.Person" scope="prototype"/>
@Test
public void test3() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("bean5.xml"); Person person1 = ioc.getBean("person", Person.class);
Person person2 = ioc.getBean("person", Person.class);
System.out.println("person1:" + person1);
System.out.println("person3:" + person2); }
singleton和prototype区别:
singleton单实例:加载spring配置文件时候就会创建单实例对象
prototype多实例:不是在加载Spring配置文件时候创建对象,而是在调用getBean方法时候创建多实例对象