Spring概述
Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架。
其核心为:
- IoC(Inverse Of Control:反转控制)
- AOP(Aspect Oriented Programming:面向切面编程)。
IOC
IOC(控制反转):把创建对象的权利交给spring框架,它包括依赖注入(DI)和依赖查找。
IOC中的工厂类:
BeanFactory 和 ApplicationContext
- BeanFactory 是 Spring 容器中的顶层接口。
- ApplicationContext 是它的子接口。
- BeanFactory 和 ApplicationContext 的区别:
创建对象的时间点不一样。 - ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。(单例)
BeanFactory:什么使用什么时候创建对象。(多例)
ApplicationContext 接口的实现类
- ClassPathXmlApplicationContext:
它是从类的根路径下加载配置文件 (推荐使用这种) - FileSystemXmlApplicationContext:
它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。 - AnnotationConfigApplicationContext:
当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。
//扫描内路径下的配置文件,创建Spring的IOC容器
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
//根据配置文件从IOC容器中获取Bean实例
HelloWorld helloWorld =(HelloWorld) context.getBean("hello");
**bean标签
- id:给对象在容器中提供一个唯一标识。用于获取对象。
- class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
scope:指定对象的作用范围。
- singleton :默认值,单例的.
- prototype :多例的.常用的属性**
IOC操作:
IOC操作:就是对象的创建交给Spring进行操作,创建对象有两种方式 ioc的配置文件方式、ioc的注解方式。
实例化 Bean 的三种方式
public class HelloWorld {
private String name;
public HelloWorld() {
System.out.println("对象已经被创建了");
}
public HelloWorld(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public void sayHello(){
System.out.println("hello "+name);
}
}
第一种方式:使用默认无参构造函数
<bean id="hello" class="zlb.demo01.HelloWorld">
<constructor-arg name="name" value="Spring"></constructor-arg>
</bean>
在默认情况下:
它会根据默认无参构造函数来创建类对象。如果 bean 中没有默认无参构造函数,将会创建失败。
第二种方式:spring 管理静态工厂-使用静态工厂的方法创建对象
//静态工厂,使用静态工厂的方法创建对象
public class BeanFactoryDemo {
public static HelloWorld create(){
return new HelloWorld();
}}
<bean id="hello" class="zlb.demo01.BeanFactoryDemo" factory-method="create"></bean>
此种方式是:
使用 StaticFactory 类中的静态方法 createAccountService 创建对象,并存入 spring 容器
id 属性:指定 bean 的 id,用于从容器中获取
class 属性:指定静态工厂的全限定类名
factory-method 属性:指定生产对象的静态方法
依赖注入的方法(基于xml配置文件)
构造函数注入
import java.util.Date;
public class HelloWorld {
private String name;
private Date bir;
public HelloWorld() {
System.out.println("对象已经被创建了");
}
public HelloWorld(String name, Date bir) {
this.name = name;
this.bir = bir;
}
public void setName(String name) {
this.name = name;
}
public void setBir(Date bir) {
this.bir = bir;
}
public void sayHello(){
System.out.println("hello "+name);
}
}
<!-- 使用构造函数的方式,给 service 中的属性传值
要求:
类中需要提供一个对应参数列表的构造函数。
涉及的标签:
constructor-arg
常用属性:
name:指定参数在构造函数中的名称 用这个找给谁赋值
value:它能赋的值是基本数据类型和 String 类型
ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean
<bean id="hello" class="zlb.demo01.HelloWorld">
<constructor-arg name="name" value="Spring" ></constructor-arg>
<constructor-arg name="bir" ref="date"></constructor-arg>
</bean>
<bean name="date" class="java.util.Date"></bean>
set 方法注入
<!-- 通过配置文件给 bean 中的属性传值:使用 set 方法的方式
涉及的标签:
property
属性:
name:找的是类中 set 方法后面的部分
ref:给属性赋值是其他 bean 类型的
value:给属性赋值是基本数据类型和 string 类型的
实际开发中,此种方式用的较多。
<bean id="hello" class="zlb.demo01.HelloWorld" >
<property name="name" value="Spring"></property>
<property name="bir" ref="date"></property>
</bean>
<bean name="date" class="java.util.Date"></bean>
使用 p 名称空间注入数据
<bean id="hello" class="zlb.demo01.HelloWorld" p:name="Spring" p:bir-ref="date"></bean>
<bean name="date" class="java.util.Date"></bean>
基于注解的 IOC 配置
使用@Componet注解配置管理的资源
@Component
public class HelloWorld {
private String name;
private Date bir;
public HelloWorld() {
System.out.println("对象已经被创建了");
}
public HelloWorld(String name, Date bir) {
this.name = name;
this.bir = bir;
}
public void setName(String name) {
this.name = name;
}
public void setBir(Date bir) {
this.bir = bir;
}
public void sayHello(){
System.out.println("hello "+name);
}
}
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--告知spring容器要扫描的包-->
<context:component-scan base-package="zlb.demo01"></context:component-scan>
</beans>
常用注解
@Compoent
用来创建对象的
相当于 < bean id=" " value=" ">
作用:
把资源让 spring 来管理。相当于在 xml 中配置一个 bean。
属性:
value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首字母小写。
@Controller @Service @Repository
@Controller:一般用于表现层的注解。
@Service:一般用于业务层的注解。
@Repository:一般用于持久层的注解。
@Autowired
用于注入数据的
相当于:
<property name="" ref="">
<property name="" value="">
作用:
自动按照类型注入。当使用注解注入属性时,set 方法可以省略。它只能注入其他 bean 类型。当有多个类型匹配时,使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到就报错。
@Qualifier
作用:
在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和
@Autowire 一起使用;但是给方法参数注入时,可以独立使用。
属性:
value:指定 bean 的 id。
public interface MyInterface {
void say();
}
@Component
public class MyInterfaceImpl1 implements MyInterface{
public void say() {
System.out.println("hello,我是接口的实现类1");
}
}
@Component
public class MyInterfaceImpl2 implements MyInterface {
public void say() {
System.out.println("hello ,我是接口的实现类对象2");
}
}
@Component
public class App {
@Autowired
//@Qualifier("myInterfaceImpl1")
@Qualifier("myInterfaceImpl2")
private MyInterface myInterface;
public void method(){
myInterface.say();
}
}
上述代码通过@Autowired注入,有2个匹配类型,这时就需要用到@Qualifier注解
@Resource
作用:
直接按照 Bean 的 id 注入。它也只能注入其他 bean 类型。
属性:
name:指定 bean 的 id。
用它可以代替上述代码中的@Autowired和@Qualifier
/*@Autowired
//@Qualifier("myInterfaceImpl1")
@Qualifier("myInterfaceImpl2")*/
//@Resource(name = "myInterfaceImpl1")
@Resource(name = "myInterfaceImpl2")
@Value
作用:
注入基本数据类型和 String 类型数据的
属性:
value:用于指定值
@Value("胡歌")
private String name;
@Value("2019/8/23")
private Date bir;