spring框架(spring全家桶)
spring FrameWork
springBoot+springCloud+springCloud Data Flow
一:spring的两大核心机制:
- IoC :工厂模式
- AOP:代理模式
1:Ioc
Ioc是Spring是框架的灵魂,控制反转。
Student student = new Student();
lombok 可以帮助开发这者自动生成get set 方法..
在idea中使用必须安装插件
@Data注解
@AllArgsConstructor注解全参的构造
@NoArgsConstructor注解构造无参
设置mavend的版本太低:
- file - projectStructure.. - Modules - Language Level:jdk8以上
- File --> Settings --> Build,Execution,Deployment --> Compiler --> java Compiler
开发过程:
创建Maven工程,pom.xml导入依赖。
xml</p></li> </ol> ¨K40K¨K87K在resources路径下创建spring.xml
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" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="student" class="com.southwind.entity.Student"></bean> </beans>3.IoC容器通过读取spring.xml配置文件,加载bean标签来创建对象
4.调用API来获取IoC中的已经创建的对象
java //传统的开发方式是手动开发对象 // Student a = new Student(); // System.out.println(a); //IoC容器自动创建对线,开发者只需要取出对象即可 ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring.xml"); Student student = (Student)applicationContext.getBean("student"); System.out.println(student); }
IoC容器创建Bean的两种方式:
无参构造
<bean id="student" class="com.southwind.entity.Student"></bean>给成员变量赋值(原理是利用set 方法修改的)
<bean id="student" class="com.southwind.entity.Student">
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
<property name="age"value="20"></property>
</bean>IoC取对象:
id取
Student student = (Student)applicationContext.getBean("student");实体类的实例类取
Student student = (Student)applicationContext.getBean(Student.class);实体类有多个抛异常
有参构造
<bean id="student1" class="com.southwind.entity.Student">
<constructor-arg name="id" value="3"></constructor-arg>
<constructor-arg name="name" value="王五"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
</bean><bean id="student1" class="com.southwind.entity.Student">
<constructor-arg index="1" value="3"></constructor-arg>
<constructor-arg index="0" value="王五"></constructor-arg>
<constructor-arg index="2" value="18"></constructor-arg>
</bean>取对象:
ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring.xml");
Student student = (Student)applicationContext.getBean("student1");
// Student student = (Student)applicationContext.getBean(Student.class);
System.out.println(student);bean中包含特殊字符可以:**
]]> **<bean id ="classes" class="com.southwind.entity.Classes">
<property name="id" value="1"></property>
<property name="name">
<value><![CDATA[<一班>]]></value>
</property>
</bean>IoC Di
Di 指的是bean之间的依赖注入,设置对象之间的级联关系
Classes:
package com.southwind.entity;
import lombok.Data;
@Data
public class Classes {
private Integer id;
private String name;
}Student:
package com.southwind.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer id;
private String name;
private Integer age;
private Classes classes;
}spring-di.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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--Classes-->
<bean id ="classes" class="com.southwind.entity.Classes">
<property name="id" value="1"></property>
<property name="name" value="1班"></property>
</bean>
<!-- Student-->
<bean id ="student" class="com.southwind.entity.Student">
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
<property name="age" value="18"></property>
<property name="classes" ref="classes"></property>
</bean>
</beans>Test2:
package com.southwind.test;
import com.southwind.entity.Classes;
import com.southwind.entity.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
//IoC容器自动创建对线,开发者只需要取出对象即可
ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring-di.xml");
// String[] names = applicationContext.getBeanDefinitionNames();
// for (String name:names){
// System.out.println(name);
// }
Student student = (Student)applicationContext.getBean("student");
Classes classes =(Classes)applicationContext.getBean("classes");
System.out.println(student);
}
}Bean对象的级联学要使用ref属性来完成映射,而不能直接使用value否值会抛出类型转化异常:
Classes:
package com.southwind.entity;
import lombok.Data;
import javax.swing.*;
import java.util.List;
@Data
public class Classes {
private Integer id;
private String name;
private List<Student> studentList;
}spring-di.xml:
<!--Classes-->
<bean id ="classes" class="com.southwind.entity.Classes">
<property name="id" value="1"></property>
<property name="name">
<value><![CDATA[<一班>]]></value>
</property>
<property name="studentList">
<list>
<ref bean="student" ></ref>
<ref bean="student1" ></ref>
</list>
</property>
</bean>但是要注意不能闭环
spring中的Bean
bean 是根据scope 来生成的,表示bean的作用域,scope有4种“
singleton ,单例,表示通过Spring容器获取对象的唯一性 默认
(无论取不取,只要加载IoC容器,就创建对象)
prototype, 原型,表示通过Spring容器获取的对象是不同的
(如果不取Bean就不创建对象,取几个就创建几个对象)
request ,请求,表示在一次HTTP请求内有效
session ,会话,表示在一个用户内有效
requestion、session仅在web中有效
Spring的继承
Spring的继承不同于Java ,区别:java中的继承是真对类的,SPring中的继承是针对对象的(Bean)
Spring的继承中,子Bean可以以继承父Bean中的值
通过parent设置继承关系,同时值bean的值来继承和覆盖
<bean id="user1" class="com.southwind.entity.User" scope="prototype" >
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
</bean>
<bean id="user" class="com.southwind.entity.User" scope="prototype" parent="user1">
<property name="name" value="李四"></property>
</bean>即使是两个不同的类,只是赋值。(属性名一样必须,不一样抛异常)(只要成员变量一样就行)
Spring的依赖:
用来设置两个Bean的顺序
IoC容器默认情况是通过spring.xml中bean的配置顺序来决定创建的顺序
在不修改spring.xml来depends-on=""修改
<bean id="user" class="com.southwind.entity.User" depends-on="student">
</bean>
<bean id="student" class="com.southwind.entity.Student"></bean>Spring读取外部资源
实际开发中,数据库的资源一般会单独保存起来。一般会保存到后缀为properties的文件中,方便维护和修改,如果Spring加载资源,就需要在spring.xml中读取properties中的资源
xxx.properties
user=root
password=root
url = jdbc:mysql://localhost:3306/library
driverName=com.mysql.cj.jdbc.Driverspring-xx.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.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 导入外部资源-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--SpringEL-->
<bean id="dataSource" class="com.southwind.entity.DataSouse ">
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="url" value="${url}"></property>
<property name="driverName" value="${driverName}"></property>
</bean>
</beans>DataSource:
package com.southwind.entity;
import lombok.Data;
@Data
public class DataSouse {
private String user;
private String password;
private String url;
private String driverName;
}测试类:
package com.southwind.test;
import com.southwind.entity.DataSouse;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test4 {
public static void main(String[] args) {
ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring-property.xml");
DataSouse dataSouse = (DataSouse)applicationContext.getBean("dataSource");
System.out.println(dataSouse);
}
}Spring p 命名空间
p 命名空间简化Bean的配置
Spring-p.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: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="student" class="com.southwind.entity.Student" p:id="1" p:name="张三"></bean>
</beans>测试类:
package com.southwind.test;
import com.southwind.entity.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test5 {
public static void main(String[] args) {
ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring-p.xml");
Student student = (Student)applicationContext.getBean("student");
System.out.println(student);
}
}如果和级联一样:也是p:age-ref=""写类
同时也要引入:
xmlns:p="http://www.springframework.org/schema/p"<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">Spring的工厂方法:
IoC通过工厂模式创建bean对线有两种方式:
静态工厂模式
实例工厂模式
区别在与:静态工厂不需要实例化,实例工厂需要实例化
1.静态工厂
实体类Car
package com.southwind.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Car {
private Integer num;
private String brand;
}创建静态工厂,使用静态工厂方法:
package com.southwind.factory;
import com.southwind.entity.Car;
import java.util.HashMap;
import java.util.Map;
public class StaticCarFactory {
private static Map<Integer, Car> carMap;
static {
carMap=new HashMap<>();
carMap.put(1,new Car(1,"奥迪"));
carMap.put(1,new Car(1,"奥拓"));
}
public static Car getCar(Integer num){
return carMap.get(num);
}
}
3.Spring-xx.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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="car1" class="com.southwind.factory.StaticCarFactory" factory-method="getCar">
<constructor-arg value="1"></constructor-arg>
</bean>
</beans>factory-method 是指向静态方法
constructor-arg value="1” 是指向传入的参数
测试类:
package com.southwind.test;
import com.southwind.entity.Car;
import com.southwind.factory.StaticCarFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test6 {
public static void main(String[] args) {
// Car car = StaticCarFactory.getCar(1);
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring-factory.xml");
Car car = (Car)applicationContext.getBean("car1");
System.out.println(car);
}
}2.实例工厂方法:
1.创建实例工厂类、工厂方法
package com.southwind.factory;
import com.southwind.entity.Car;
import java.util.HashMap;
import java.util.Map;
public class InstanceCarFactory {
private Map<Integer, Car> carMap;
public InstanceCarFactory(){
carMap= new HashMap<>();
carMap.put(1,new Car(1,"奥迪"));
carMap.put(1,new Car(1,"奥托"));
}
public Car getCar(Integer num){
return carMap.get(num);
}
}2.spring-xx.xml
<!-- 实例工厂-->
<bean id="instanceCarFactory" class="com.southwind.factory.InstanceCarFactory"></bean>
<!-- 通过实例工厂获取Car-->
<bean id="car2" factory-bean="instanceCarFactory" factory-method="getCar">
<constructor-arg value="1"></constructor-arg>
</bean>测试类:
package com.southwind.test;
import com.southwind.entity.Car;
import com.southwind.factory.StaticCarFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test6 {
public static void main(String[] args) {
// Car car = StaticCarFactory.getCar(1);
// ApplicationContext applicationContext= new ClassPathXmlApplicationContext("spring-factory.xml");
// Car car = (Car)applicationContext.getBean("car1");
// System.out.println(car);
// }
// 实例工厂
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-factory.xml");
Car car = (Car) applicationContext.getBean("car2");
System.out.println(car);
}
}区别:
- 静态工厂方法创建Car对象,不需要创建Car对象,因为静态工厂的静态方法,不需要通过创建对象即可调用。spring-xx.xml中只需要配置一个Bean,即最终的Car即可。
- 实例工厂方法创建Car对象,需要实例化工厂对象,因为getCar()方法是非静态的,就必须通过实例化的对象才能调用,所以就必须创建工厂对象,spring。xml中,要配置两个Bean一个是工厂对象,一个是Car 对象。
Spring IoC 自动装载 autowire:
自动装载是Spring提供的一种更加简单的方式,来完成DI,不需要手动配置property ,IoC容器会自动选择Bean玩成注入。
自动装载俩种:
byName ,通过属性名完成自动装载
byType,通过属性对应的数据类型完成自动装载
byName
1.创建实体类
package com.southwind.entity;
import lombok.Data;
@Data
public class Presson {
private Integer Id;
private String name;
private Car car;
}
2.在spring.xml中配置Car和Person的Bean,通过自动装载完成依赖注入
<bean id="person" class="com.southwind.entity.Presson" autowire="byName">
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
</bean>
<bean id="car" class="com.southwind.entity.Car">
<constructor-arg name="num" value="1"> </constructor-arg>
<constructor-arg name="brand" value="奥迪"></constructor-arg>
</bean>测试:
package com.southwind.test;
import com.southwind.entity.Presson;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test7 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-autowire.xml");
Presson preson =(Presson)applicationContext.getBean("person");
System.out.println(preson);
}
}byType:
1.实体类
2.在spring.xml中配置Car和Person的Bean,通过自动装载完成依赖注入
<bean id="person" class="com.southwind.entity.Presson" autowire="byType">
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
</bean>
<bean id="car" class="com.southwind.entity.Car">
<constructor-arg name="num" value="1"> </constructor-arg>
<constructor-arg name="brand" value="奥迪"></constructor-arg>
</bean>注意:
使用byType进行自动装载时,多个会有异常。
Spring IoC基于注解的开发
SpingIoC的作用帮助开发者创建项目中所需要的Bean,同时完成Bean之间的依赖注入关系。DI
实现功能有两种方式:
基于xml
基于注解
基于注解的配置有两部:
配置自动扫包
xml <!-- 自动扫包--> <context:component-scan base-package="com.southwind.entity"></context:component-scan>添加注解: @Component (默认首字母类第一个字母小写为名字)
java package com.southwind.entity;import lombok.Data;
import org.springframework.stereotype.Component;@Data
@Component
public class Repository {
private DataSouse dataSouse;
}
改名字:@Component(value = "myrepo")
java package com.southwind.entity;import lombok.Data;
import org.springframework.stereotype.Component;@Data
@Component(value = "myrepo")
public class Repository {
private DataSouse dataSouse;
}
分析注入得到类:
String[] s= applicationContext.getBeanDefinitionNames();
for(String name :s){
System.out.println(name);
}
DI:
package com.southwind.entity;
import lombok.Data;
import org.springframework.stereotype.Component;
@Data
@Component
public class DataSouse {
private String user;
private String password;
private String url;
private String driverName;
}自动装载:@Autowired(默认时byType)
package com.southwind.entity;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Data
@Component
public class Repository {
@Autowired
private DataSouse dataSouse;
}要改变为byName()配合 @Qualifier(value="DS")
@Data
@Component
public class Repository {
@Autowired
@Qualifier(value="DS")
private DataSouse dataSouse;
}实体类中的普通的成员变量可以通过@Value进行赋值
@Data
@Component(value = "DS")
public class DataSouse {
@Value("root")
private String user;
@Value("root")
private String password;
@Value("jdbc:mysql://localhost:3306/library")
private String url;
@Value("com.mysql.cj.jdbc.Driver")
private String driverName;
}实际开发的使用
实际开发中会将程序分为3层:
- Controller
- Servlet
- Repository(DAO)
关系Controller 调运Servlet 调运 Repository(DAO)
@Component 注解是将标注的类加载到IoC容器中,实际开发中可以分别根据
@Controller 控制层
@Service 业务层
@Repository 持久层
代码:
1.
package com.southwind.Repository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
public interface myRepository {
public String domyRepository(Double score);
}package com.southwind.Repository.impl;
import com.southwind.Repository.myRepository;
import org.springframework.stereotype.Repository;
@Repository
public class mymyRepositoryImpl implements myRepository {
@Override
public String domyRepository(Double score) {
String result="";
if(score<60){
result="不及格";
}else if(score>=60&&score<80){
result="合格";
}else {
result="优秀";
}
return result;
}
}2.
package com.southwind.Service;
import org.springframework.stereotype.Component;
public interface myService {
public String doSrvice(Double score);
}package com.southwind.Service.impl;
import com.southwind.Repository.myRepository;
import com.southwind.Service.myService;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Setter
@Service
public class myServiceImpl implements myService {
@Autowired
private myRepository myRepository;
@Override
public String doSrvice( Double score) {
return myRepository.domyRepository(score);
}
}3.
package com.southwind.Controller;
import com.southwind.Service.myService;
import lombok.Data;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller(value = "a")
@Data
public class myControlller {
//客户端请求
@Autowired
private com.southwind.Service.myService myService;
; public String service(Double score){
return myService.doSrvice(score);
}
}配置:
<?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.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- <bean id="repository" class="com.southwind.entity.Repository"></bean>-->
<!-- 自动扫包-->
<context:component-scan base-package="com.southwind"></context:component-scan>
<!-- <bean id="controller" class="com.southwind.Controller.myControlller">-->
<!-- <property name="myService" ref="service"></property>-->
<!-- </bean>-->
<!-- <bean id="service" class="com.southwind.Service.impl.myServiceImpl">-->
<!-- <property name="myRepository" ref="repository"></property>-->
<!-- </bean>-->
<!-- <bean id="repository" class="com.southwind.Repository.impl.mymyRepositoryImpl"></bean>-->
</beans>测试类:
package com.southwind.test;
import com.southwind.Controller.myControlller;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test9 {
public static void main(String[] args) {
ApplicationContext applicationContext =new ClassPathXmlApplicationContext("spring-annotation.xml");
// String[] s= applicationContext.getBeanDefinitionNames();
// for(String name :s){
// System.out.println(name);
// }
// 客户端请求
myControlller myControlller =(myControlller) applicationContext.getBean("a") ;
String result = myControlller.service(new Double(77));
System.out.println(result);
}
}Spring IoC的底层实现:
核心技术: XML解析+反射
具体思路:
- 根据需求编写XML文件,配置需要的创建的Bean.
- 编写程序需要的XML文件,获取Bean的相关信息,类,属性,id
- 根据第二步骤获得到的信息,结合反射机制动态的创建对象,同时完成属性的赋值
- 将创建好的bean存入Map集合中,设置key就是bean的id的值,value就是bean的对象
- 提供方法从Map中获得对应的value
浙公网安备 33010602011771号