狂人日记day12 && day13
spring
-
spring 是一个开源的免费框架
-
spring是一个轻量级的非入侵的框架
-
控制反转 面向切面编程
-
支持事务的处理,对框架整合的支持
springmvc
org.springframework spring-webmvc 5.3.7
org.springframework spring-jdbc 5.3.7
组成
spring官网:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html
-
springboot
-
- 快速开发的脚手架
- 可以快速开发单个微服务
-
-
springcloud
-
-
- 基于springboot实现的
-
学会spring和springmvc后再学springboot
弊端:
-
发展太久 违背原来的理念
-
配置十分繁琐
IOC 理论推导
控制反转
之前的业务中,用户的需求会影响原来的代码,我们需要用户的需求去修改原来代码
使用set接口,发生了革命性变化
public void setUserdao(userdao userdao) { this.userdao = userdao; }
- 之前程序主动创建对象,控制权在程序员
- 使用set后 程序不在具有主动性 而是变成了被动的接受对象
这种思想从本质上解决了问题,我们不用再去管理对象的创建。可以更多精力在业务的实现上
这是ioc的原型
hello spring
传统容器创建对象,现在由spring创建
Ioc思想变换
ioc 创建对象的方式
默认无参构造
<bean id="user" class="com.bai.pojo.user">
<constructor-arg index="0" value="bai"/>
</bean>
ref 是引用spring容器中创建好的对象
value是具体的值
spring 配置
别名
添加了别名也可以用别名获取对象
<alias name ="user" alias ="user2"/>
id bean的唯一标识符,相当于对象名
import
一般用于团队开发使用
不同的类注册在不同的bean中用import将不同beans。xml合并为总的 最后使用一个总的就可以
applicationContext
构造器注入
set注入
- 依赖注入:set注入
- 依赖:bean对象的创建依赖于容器
- 注入:bean对象中的所有属性,由容器来注入
其他方式
p命名空间
c命名空间
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!--p命名注入--> <bean id ="user" class = "com.bai.pojo.user" p:name = "bai" p:age = "18"/> <!--c命名--> <bean id ="user2" class = "com.bai.pojo.user" c:name = "baijiapeng" c:age = "18"/> </beans>
测试
@Test public void test2(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); user user = context.getBean("user2", user.class); System.out.println(user);
注意点 p命名和c命名空间不能直接使用,需要导入xml约束
bean作用域
1.单例模式
singleton scope
创建所有实例只有一个
@Test public void test2(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); user user = context.getBean("user2", user.class); user user2 = context.getBean("user2",user.class); System.out.println(user.hashCode() == user2.hashCode()); } }
返回结果:
ture 说明是一个
2.原型模式:
每次get时都会产生一个新对象
<bean id ="user2" class = "com.bai.pojo.user" c:name = "baijiapeng" c:age = "18" scope ="prototype"/>
同样测验返回false 说明不是一个
3.其余的request session application
其余在web开发中使用
bean的自动装配
- 自动装配是spring满足bean依赖的一种方式
- spring会在上下文中自动寻找并自动给bean装配属性
在spring中有三种自动装配的方式
- 在xml中显示的配置
- 在java中显示配置
- 隐式的自动装配bean
测试
环境:一个人有两个宠物
错误
Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
解决办法:
打开idea设置,搜索框输入‘async’,去掉如下勾成功解决
byname
会自动在容器上下文中查找和自己对象方法对应的bean id 要和set方法的命名一致
<bean id="people" class="com.bai.poto.people" autowire="byName">
by type
会自动在容器上下文中查找和自己对象类型相同的bean
弊端 – 必须全局唯一
注解实现自动装配
要使用注解
1.导入约束
2.配置注解的支持
注意:context:annotation-config/
<?xml version="1.0" encoding="UTF-8"?>
@autowried
直接在属性上使用即可
也可以在set方法中使用
使用autowired可以不用编写set方法 前提在ioc(spring)容器中存在 且符合名字byname
@nullable 字段标记了这个注解 说明这个注解可以为null
若果@autowried环境比较复杂无法通过一个@autowried
完成 可以配合@qualifier(value =“xxx”)一起使用
@Autowired private cat cat; @Autowired private dog dog; private String name;
– 通过@resource –
- 这个没有使用明白
使用注解开发
使用注解需要导入context约束,增加注解的支持
-
bean
-
属性如何注入
-
衍生的注解\
@Repository
@Service
@Controller
@Component
功能一样都是将某个类注册到spring容器中装配
4 .自动装配
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MzeoDafG-1621775135028)(/Users/suannai/Library/Application Support/typora-user-images/image-20210523190257639.png)]
5.作用域
@Scope("singleton")
小结:
xml与注解:
-
xml更万能
- 注解不是自己的类使用不了 维护相对复杂
-
xml用来管理bean
-
注解管理属性的输入
-
只需要注意一个问题:必须要让注解生效 开启注解支持
使用java的方式配置springconfiguration
在spring4后变成了核心功能
@Component public class user { private String name; public String getName() { return name; } @Value("bai") public void setName(String name) { this.name = name; } @Override public String toString() { return "user{" + "name='" + name + '\'' + '}'; } }
@Configuration @ComponentScan("com.bai.pojo") public class baiconfig { //注册一个bean相当于之前写的一个bean标签 //这个方法的名字就相当于bean中的标签 返回值 相当于class @Bean public user getuser(){ return new user(); } }
@Configuration @ComponentScan("com.bai.pojo") @Import(baiconfig.class) public class baiconfig2 { @Bean public user getuser(){ return new user(); } }
import com.bai.pojo.user; import config.baiconfig; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class mytest { public static void main(String[] args) { //如果完全按照配置类方式去做,只能通过annotationconfig ApplicationContext context = new AnnotationConfigApplicationContext(baiconfig.class); user getuser =(user)context.getBean("getuser"); System.out.println(getuser.getName()); } }
代理模式
代理模式的分类
- 静态代理
1.接口
package demo1; public interface rent { public void rent(); }
2.真实角色
package demo1; public class host implements rent{ public void rent(){ System.out.println("房东要出租房子"); } }
3.代理角色
package demo1; public class proxy implements rent{ private host host; public proxy(){} public proxy(host host){ this.host=host; } public void rent(){ host.rent(); } public void seehouse(){ System.out.println("中介看房"); } public void hetong(){ System.out.println("签合同"); } public void fare(){ System.out.println("收中介费"); } }
4.客户端访问角色
package demo1; public class client { public static void main(String[] args) { //房东要租房子 host host = new host(); //代理,中介帮房子租房子 proxy proxy = new proxy(host); //直接找中介 proxy.rent(); proxy.hetong(); proxy.fare(); proxy.seehouse(); } }
-
- 抽象角色:一般会使用接口或抽象类
- 真实角色:被代理的角色
- 代理角色:代理真实角色
- 客户:访问代理对象的人
好处:
- 使真实角色更加纯粹
- 公共也就交给代理角色 实现业务分工
- 发生拓展方便集中管理
缺点:
- 一个真实角色就会产生一个代理角色,代码量翻倍
加深理解:
Spring -08 -demo2 代码
-
动态代理
-
- 和静态代理角色一样
-
- 是动态生成的,不是写好的
- 动态代理分两大类:基于接口的动态代理,基于类的动态代理
-
- 基于接口-jdk动态代理
- 基于类 cglib
- 基于java字节码实现:javassist
了解两个类 proxy , invocationHandler:调用处理程序
- 动态代理类代理的是一恶搞接口,一般代理的是一类业务