目录
Spring概念
spring是一个轻量级,非侵入式框架
Spring七大模块
详细看:
(141条消息) Spring七大模块详解_spring功能模块_压到我腿毛了的博客-CSDN博客
Spring Boot 和 Spring Cloud
可以基于spring boot可以快速开发单个微服务,Spring cloud是基于spring boot,并且都是约定大于配置
IOC
IOC是一种控制反转的一种思想,依赖注入DI则是IOC的一种实现方式。控制反转则是将对象的创建交给了spring,通过xml的形式或注解的方式进入创建对象。使用对象的时候使用spring上下文ApplicationContext来实现获取对象
import lombok.Data;
/**
* @author : lvyiting
* @date : 2023-04-17 14:22
**/
@Data
public class Dog {
private String name;
private Integer age;
}
<?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="dog" class="cn.ting.springstudy.entity.Dog">
<property name="age" value="22"></property>
<property name="name" value="小吕"></property>
</bean>
</beans>
public static void main(String[] args) {
//spring上下文
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Object dog = context.getBean("dog");
System.out.println(dog.toString());
}
spring创建对象时进行参数的赋值默认是无参构造,有参构造可以通过constructor-arg这个参数实现
<bean id="dog" class="cn.ting.springstudy.entity.Dog">
<!-- <property name="age" value="22"></property>-->
<!-- <property name="name" value="小吕"></property>-->
<constructor-arg name="age" value="23"/>
<constructor-arg name="name" value="小张"/>
</bean>
总结:在配置文件加载的时候,容器中管理的对象就已经初始化了
补充:对象初始化(实例化)的过程
/**
* @author : lvyiting
* @date : 2023-04-17 16:35
**/
/**
* Created by jay.zhou on 2018/2/22.
*/
public class Fu {
public int count = 1;
private String name;
static {
System.out.println("父类的class文件被JVM加载,类中所有字段被设置为默认值,int类型的值的默认值是0");
}
{
System.out.println(count);
System.out.println("根据count的值知道,count的值被显示初始化为1");
System.out.println("父类的构造代码块执行");
count = 2;
System.out.println("count的值已经被修改");
}
public Fu(String name) {
this.name = name;
System.out.println("子类的有参构造函数执行");
}
public Fu() {
super();
System.out.println("父类的无参构造函数执行");
System.out.println(count);
}
}
class Zi extends Fu {
private String name;
static {
System.out.println("子类的class文件被JVM加载,类中所有字段被设置为默认值,int类型的值的默认值是0");
}
{
System.out.println("子类的构造代码块执行");
}
public Zi(String name) {
this.name = name;
System.out.println("子类的有参构造函数执行");
}
public Zi() {
super();
System.out.println("子类的无参构造函数执行");
}
public static void main(String[] args) {
new Zi();
}
}
结果:
Spring的配置参数
上面代码基本都包含了spring的配置参数,这里补充一个import,它是在团队开发时使用的,作用是将所有配置文件导入到一个配置文件中,访问所有对象只通过一个配置文件
<import resource="Beans.xml"></import>
DI依赖注入
三种方式:
- 基于属性注入
- 基于 setter 方法注入
- 基于构造器注入
各种类型的依赖注入
package cn.ting.springstudy.entity;
import lombok.Data;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
/**
* @author : lvyiting
* @date : 2023-04-18 10:12
**/
@Data
public class People {
//对象
private Address address;
//List
private List<String> love;
//map
private Map<Integer,String> card;
//String
private String name;
//数组
private String[] books;
//null
private String wife;
//set
private Set<String> games;
//Properties
private Properties info;
}
<?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="dog" class="cn.ting.springstudy.entity.Dog">
<!-- <property name="age" value="22"></property>-->
<!-- <property name="name" value="小吕"></property>-->
<constructor-arg name="age" value="23"/>
<constructor-arg name="name" value="小张"/>
</bean>
<bean id="cat" class="cn.ting.springstudy.entity.Cat">
</bean>
<bean id="address" class="cn.ting.springstudy.entity.Address">
<property name="name" value="北京"></property>
</bean>
<bean id="people" class="cn.ting.springstudy.entity.People">
<!-- 基本-->
<property name="name" value="吕怡婷"></property>
<!-- 对象-->
<property name="address" ref="address"/>
<!-- 数组-->
<property name="books">
<array>
<value>三国演义</value>
<value>红楼梦</value>
<value>第七天</value>
</array>
</property>
<!-- list-->
<property name="love">
<list>
<value>羽毛球</value>
<value>篮球</value>
<value>吃饭</value>
</list>
</property>
<!-- map-->
<property name="card">
<map>
<entry key="0" value="奥特曼"></entry>
<entry key="1" value="白雪公主"></entry>
<entry key="2" value="天线"></entry>
</map>
</property>
<!-- set-->
<property name="games">
<set>
<value>吃鸡</value>
<value>王者荣耀</value>
</set>
</property>
<!-- Properties-->
<property name="info">
<props>
<prop key="学号">19310320208</prop>
</props>
</property>
<!-- null-->
<property name="wife">
<null></null>
</property>
</bean>
</beans>
结果输出:
People(address=Address(name=北京), love=[羽毛球, 篮球, 吃饭], card={0=奥特曼, 1=白雪公主, 2=天线}, name=吕怡婷, books=[三国演义, 红楼梦, 第七天], wife=null, games=[吃鸡, 王者荣耀], info={学号=19310320208})
P命名空间
注意p命令使用之前必须要添加xml约束
xmlns:p="http://www.springframework.org/schema/p"
<?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="cat" class="cn.ting.springstudy.entity.Cat" p:name="xxxx">
</bean>
</beans>
Beans的作用域
单列模式(默认)、多列模式prototype等。不重要
Bean的自动装配
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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
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:component-scan base-package="cn.ting.springstudy.entity"/>
<context:annotation-config></context:annotation-config>
</beans>
自动注入类的注解:
1.entity层面:@Component
2.dao层面:@Repository
3.service层面:@Service
4.controller层面:@Controller
/**
* @author : lvyiting
* @date : 2023-04-18 14:09
**/
@Data
@Configuration
public class Book {
@Value("小绿书")
private String name;
private Dog dog;
private Cat cat;
@Bean
public Book getBook(){
return new Book();
}
}
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Book.class);
Object bean = applicationContext.getBean("getBook");
System.out.println(bean.toString());
}
补充:代理模式
代理模式需要三个角色,抽象角色(接口)、真实角色(实现类)和代理角色(实现类)。真实的角色只需要专注自己需要做的事情,代理角色可以帮助真实角色做事情,同时还可以做额外的事情。分类为静态代理和动态代理,动态代理需要用到反射。
动态代理分为两大类,基于接口的动态代理(JDK动态代理),基于类的动态代理(Cglib),学习动态代理必须知道两个类proxy和InvocationHandler类
public interface Rent {
void rent();
}
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东来租房咯");
}
}
/**
* @author : lvyiting
* @date : 2023-04-20 15:28
* 代理模式:代理租房
**/
public class ProxyRent implements InvocationHandler {
private Rent rent;
//代理的接口
public void setRent(Rent rent) {
this.rent = rent;
}
//获取代理
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this);
}
//处理程序
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(rent, args);
return result;
}
}
public static void main(String[] args) {
Host host = new Host();
ProxyRent proxyRent=new ProxyRent();
//设置代理角色
proxyRent.setRent(host);
//设置代理类
Rent proxy = (Rent) proxyRent.getProxy();
proxy.rent();
}