网站设计命名规范,房天下官方网站,服装网页设计图片,WordPress文章图片自动圆角1、Spring
1.1、简介 Spring:春天------给软件行业带来了春天! 2002#xff0c;首次推出了Spring框架的雏形: interface21框架! Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日,发布了1.0正式版。 Rod Johnson ,Spring Framewor…1、Spring
1.1、简介 Spring:春天------给软件行业带来了春天! 2002首次推出了Spring框架的雏形: interface21框架! Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日,发布了1.0正式版。 Rod Johnson ,Spring Framework创始人著名作者。很难想象Rod Johnson的学历真的让好多人大吃一惊他是悉尼大学的博士然而他的专业不是计算机而是音乐学。 spring理念:使现有的技术更加容易使用本身是一个大杂烩整合了现有的技术框架! SSH : Struct2 Spring Hibernate ! SSM : SpringMvc Spring Mybatis!
官网: https:/lspring.io/projects/spring-framework#overview
官方下载地址: http://repo.spring.io/release/orglspringframework/spring
GitHub: https:/lgithub.comlspring-projects/spring-framework
1 !-- https : //mvnrepository.com/artifact/org.springframework/spring-webmvc --2dependency
groupIdorg.springframework/groupId
artifactIdspring-webmvc/ artifactId
version5.2.O.RELEASE/version/ dependency
!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --8dependency
groupIdorg.springframework/groupId
artifactidspring-jdbc/artifactId
cversion5.2.0.RELEASE/version/ dependency
1.2、优点
Spring是一个开源的免费的框架容器)!Spring是一个轻量级的、非入侵式的框架!控制反转(IOC)面向切面编程(AOP) !支持事务的处理对框架整合的支持!
总结一句话: Spring就是一个轻量级的控制反转IOC)和面向切面编程AOP的框架!
2、IOC理论推导 UserDao 接口 UserDaoImpl 接口实现类 UserService 业务接口 UserServiceImpl 业务实现类
在之前的业务中用户的需求可能会影响我们原来的代码我们需要根据用户的需求去修改源代码如果程序代码量十分大修改一次的成本代价十分昂贵
我们使用一个Set接口实现已经发生了革命性的变化
//利用set动态实现值的注入
public void setUserDao(UserDao userDao) {this.userDao userDao;
}之前程序是主动创建对象控制权在程序员手上使用了Set注入后程序不再具有主动性二十变成了被动的接受对象
这种思想从本质上解决了问题我们程序员不用再去管理对象的创建系统的耦合性大大降低可以更加专注在业务的实现上这是IOC的原型
IOC本质
**控制反转loC(Inversion of Control)是一种设计思想DI(依赖注入)是实现loC的一种方法也有人认为DI只是loC的另一种说法。**没有loC的程序中我们使用面向对象编程对象的创建与对象间的依赖关系完全硬编码在程序中对象的创建由程序自己控制控制反转后将对象的创建转移给第三方个人认为所谓控制反转就是︰获得依赖对象的方式反转了。 采用XML方式配置Bean的时候Bean的定义信息是和实现分离的而采用注解的方式可以把两者合为一体Bean的定义信息直接以注解的形式定义在实现类中从而达到了零配置的目的。
控制反转是一种通过描述XML或注解并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是loC容器其实现方法是依赖注入(Dependency Injection,Dl)。
3、IOC创建对象的方式
1.使用无参构造创建对象默认
2.假设我们要使用有参构造创建对象 下标赋值 !--第一种下标赋值--
bean iduser classcom.nynu.qdy.pojo.Userconstructor-arg index0 valueqdy学Java/
/bean通过类型创建 !--第一种通过类型创建不建议使用--
bean iduser classcom.nynu.qdy.pojo.Userconstructor-arg typejava.lang.String valueqidayang/
/bean3.参数名 !--第三种方式直接通过参数名创建--bean iduser classcom.nynu.qdy.pojo.Userconstructor-arg namename value其打样//bean**总结:**在配置文件加载的时候容器中管理的对象就已经初始化了!
4、Spring配置
4.1、别名
!--如果添加了别名我们也可以通过别名获取这个对象--
alias nameuser aliasuserNew/4.2、Bean的配置
!--idbean的唯一标识符也就是我们学的对象名
classbean所对应的全限定名包名类名
name也是别名,而且name可以去多个别名--
bean iduserT classcom.nynu.qdy.pojo.UserT nameuserTNew,userTNew2 u3;u4constructor-arg namename valuexiahouxue/
/bean## 4.3import这个import一般用于团队开发使用他可以将多个配置文件导入合并为一个!假设现在项目中有多个人开发这三个人复制不同的类开发不同的类需要注册在不同的bean中我们可以利用import将所有人的beans.xml合并为一个总的!- 张三- 李四- 王五- applicationContext.xmlxmlimport resourcebeans.xml/import resourcebeans1.xml/使用的时候直接使用总的配置就可以了
5、依赖注入DI
5.1、构造器注入
前面已经说过
5.2、Set方式注入 【重点】
依赖注入Set注入 依赖bean对象的创建依赖于容器注入bean对象中的所有属性由容器来注入
【环境搭建】
1.复杂类型
2.真实测试对象
5.3、扩展方式注入
实体类
package com.nynu.qdy.pojo;public class Address {private String address;public String getAddress() {return address;}public void setAddress(String address) {this.address address;}Overridepublic String toString() {return Address{ address address \ };}
}
package com.nynu.qdy.pojo;import java.util.*;public class Student {private String name;private Address address;private String[] books;private ListString hobbys;private MapString, String card;private SetString games;private String wife;private Properties info;public String getName() {return name;}public void setName(String name) {this.name name;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address address;}public String[] getBooks() {return books;}public void setBooks(String[] books) {this.books books;}public ListString getHobbys() {return hobbys;}public void setHobbys(ListString hobbys) {this.hobbys hobbys;}public MapString, String getCard() {return card;}public void setCard(MapString, String card) {this.card card;}public SetString getGames() {return games;}public void setGames(SetString games) {this.games games;}public String getWife() {return wife;}public void setWife(String wife) {this.wife wife;}public Properties getInfo() {return info;}public void setInfo(Properties info) {this.info info;}Overridepublic String toString() {return Student{ name name \ , address address.toString() , books Arrays.toString(books) , hobbys hobbys , card card , games games , wife wife \ , info info };}
}
测试类
import com.nynu.qdy.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest {public static void main(String[] args) {ApplicationContext applicationContext new ClassPathXmlApplicationContext(beans.xml);Student student (Student) applicationContext.getBean(student);System.out.println(student.toString());}/*Student{nameqdy,addressAddress{address厦门}, books[红楼梦, 西游记, 水浒传],hobbys[听歌, 敲代码, 看电影], card{身份证1234567890, 银行卡1234345234, },games[lol, 王者, 吃鸡],wifenull,info{学号31, 性别男, 年龄19}}*/
}
完善注入信息
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdbean idaddress classcom.nynu.qdy.pojo.Addressproperty nameaddress value厦门//beanbean idstudent classcom.nynu.qdy.pojo.Student!--第一种普通值注入--property namename valueqdy/!--第二种bean注入--property nameaddress refaddress/!--第三种数组注入ref--property namebooks arrayvalue红楼梦/valuevalue西游记/valuevalue水浒传/value/array/property!--List--property namehobbyslistvalue听歌/valuevalue敲代码/valuevalue看电影/value/list/property!--Map--property namecardmapentry key身份证 value1234567890/entry key银行卡 value1234345234/entry key value//map/property!--Set--property namegamessetvaluelol/valuevalue王者/valuevalue吃鸡/value/set/property!--null--property namewife null//property!--Properties--property nameinfoprops prop key性别男/propprop key学号31/propprop key年龄19/prop/props/property/bean
/beans5.4、bean的作用域
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RShuLO7Q-1620196766093)(C:\Users\17728\AppData\Roaming\Typora\typora-user-images\image-20210501170928751.png)]
1.单例模式(Spring默认机制)
1 bean iduser2 classcom. kuang.pojo.user c:age18 c:name狂神
scopesing1eton /2.原型模式:每次从容器中get的时候都会产生一个新对象!
1bean idaccountservice classcom.something.Defau1tAccountservice
scopeprototype /3.其余的request、session、 application、这些个只能在web开发中使用到!
6、Bean的自动装配
自动装配是Spring满足bean依赖的一种方式Spring会在上下文中自动寻找并自动给bean装配属性
在Spring中有三中装配方式
在xml中显示的配置在Java中显示配置隐式的自动装配bean 【重要】
6.1、测试
环境搭建一个人有两个宠物
6.2、ByName自动装配 !--ByName:会自动在上下文中查找和自己对象set方法后面的值对应的beanid--bean idpeople classcom.nynu.qdy.pojo.People autowirebyNameproperty namename valuexq//bean6.3、ByType自动装配 bean iddog classcom.nynu.qdy.pojo.Dog/bean classcom.nynu.qdy.pojo.Cat/!--ByName:会自动在上下文中查找和自己对象set方法后面的值对应的beanid--!--ByType:会自动在上下文中查找和自己对象属性相同的bean, bean的id属性可以省略--bean idpeople classcom.nynu.qdy.pojo.People autowirebyTypeproperty namename valuexq//bean小结
ByName的时候需要保证所有的bean的id唯一并且这个bean需要和自动注入的属性的set方法的值一致ByType的时候需要保证所有的bean的calss唯一并且这个bean需要和自动注入的属性的类型一致
6.4、使用注解自动装配
要使用注解须知
导入约束,context约束 配置注解的支持 context:annotation-config/
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdcontext:annotation-config//beansAutowired
直接在属性使用即可也可以在set方法上使用使用Autowired 我们可以不用编写Set方法了前提是自动装配的属性在IOCSpring 容器中且符合名字ByName
科普
Nullable 字段标记了这个注解说明这个字段可以为null.7、使用注解开发
在Spring 4 之后要是用注解开发必须要保证aop的包导入了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kDTs6DJ4-1620196766095)(C:\Users\17728\AppData\Roaming\Typora\typora-user-images\image-20210503120036761.png)]
使用注解需要导入context约束增加注解的支持!
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdcontext:annotation-config//beansbean属性如何注解
//等价于 bean iduser classcom.nynu.qdy.pojo.User/
Component
public class User {public String name;Value(asdfas)public void setName(String name) {this.name name;}衍生的注解 Component 有几个衍生注解我们在web开发中会按照mvc三层架构分层 dao 【Repository】 service 【Service】 controller 【Controller】 这四个注解功能都是一样的都是将某个类注册到Spring中装配Bean 自动装配置
Autowired : 自动装配通过类型。名字如果Autowired不能唯一自动装配上属性则需要通过Qualifier(valuexxx)- Nullable字段标记了这个注解说明这个字段可以为null;
Resource:自动装配通过名字。类型。
作用域
//等价于 bean iduser classcom.nynu.qdy.pojo.User/
Component
Scope(prototype)
public class User {public String name;Value(asdfas)public void setName(String name) {this.name name;}小结
xml与注解
xml更加万能适合用于任何场合维护简单方便注解不是自己的类使用不了维护相对复杂
xml与注解最佳实践
xml用来管理bean注解只负责完成属性的注入我们在使用的过程中只需要注意一个问题必须让注解生效就需要开启注解的支持
!--指定扫描包这个包下的注解就会生效--context:component-scan base-packagecom.nynu.qdy/context:annotation-config/8、使用Java的方式配置Spring
我们现在要完全不使用Spring的xml配置了全权交给Java来做
JavaConfig 是Spring的一个子项目在Spring 4之后它成为了一个核心功能!
实体类
//这里这个注解的意思就是说明这个类被Spring接管了注册到了Spring容器中
Component
public class User {public String name;public String getName() {return name;}Value(其打样) //属性注入值public void setName(String name) {this.name name;}Overridepublic String toString() {return User{ name name \ };}配置文件
Configuration
//这个也会被Spring容器托管注册到容器中因为他本来就是一个Component
//Configuration 代表这是一个配置类就和我们之前看的beans.xml是一样的
ComponentScan(com.nynu.qdy)
Import(UserConfig2.class)
public class UserConfig {//注册一个bean就相当于之前写的一个bean标签//这个方法的名字就相当于bean标签中的id属性//这个方法的返回值就相当于bean标签中的class属性Beanpublic User getUser() {//就是返回要注入到bean中的对象return new User();}测试类
public class MyTest {public static void main(String[] args) {//如果完全使用了配置类方式去做我们就只能通过AnnotationConfig 上:下文来获取容器通过配置类的cLass对象加载!ApplicationContext context new AnnotationConfigApplicationContext(UserConfig.class);User user (User) context.getBean(getUser);System.out.println(user.getName());}
}
这种纯Java的配置文件在SpringBoot中随处可见
9、代理模式
为什么要学习代理模式因为就是SpringAOP的底层【SpringAOP 和 SpringMVC】
代理模式
静态代理动态代理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bzJWtsGJ-1620196766097)(C:\Users\17728\AppData\Roaming\Typora\typora-user-images\image-20210504103610050.png)]
9.1、静态代理
角色分析:
抽象角色 ︰ 一般会使用接口或者抽象类来解决真实角色 ︰ 被代理的角色代理角色 ∶ 代理真实角色代理真实角色后我们一般会做一些附属操作客户 : 访问代理对像的人!
代码步骤:
1.接口
/*** author 平卉陌路*/
public interface Rent {//出租房屋public void rent();
}2.真实角色
/*** author 平卉陌路*/
public class Host implements Rent{Overridepublic void rent() {System.out.println(房东要出租房子);}
}3.代理角色
/*** author 平卉陌路*/
public class Proxy implements Rent{private Host host;public Proxy() {}public Proxy(Host host) {this.host host;}Overridepublic void rent() {host.rent();seeHouse();signAgreement();free();}//看房public void seeHouse(){System.out.println(中介带你看房);}//签合同public void signAgreement(){System.out.println(签租赁合同);}//收中介费public void free(){System.out.println(收中介费);}
}
4.客户端访问代理角色
/*** author 平卉陌路*/
public class Client {public static void main(String[] args) {//房东要出租房子Host host new Host();/*host.rent();*///代理中介帮房东出租房子但中介会有一些附属操作Proxy proxy new Proxy(host);//你不用面对房东找中介租房即可proxy.rent();}
}代理模式的好处:
可以使真实角色的操作更加纯粹!不用去关注一些公共的业会公共也就就交给代理角色!实现了业务的分工!公共业务发生扩展的时候方便集中管理!
缺点:
一个真实角色就会产生一个代理角色;代码量会翻倍开发效率会变低
9.2、加深理解
聊聊横向AOP开发
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l6mCq27F-1620196766099)(C:\Users\17728\AppData\Roaming\Typora\typora-user-images\image-20210504142911218.png)]
9.3、动态代理
动态代理和静态代理角色一样动态代理的代理类是动态生成的不是我们直接写好的!动态代理分为两大类:基于接口的动态代理基于类的动态代理 基于接口—JDK动态代理 ----【我们在这里使用】基于类:cglibjava字节码实现: javasist
需要了解两个类: Proxy:代理InvocationHandler:调用处理程序
动态代理的好处:
可以使真实角色的操作更加纯粹!不用去关注一些公共的业务公共也就就交给代理角色!实现了业务的分工!公共业务发生扩展的时候方便集中管理!一个动态代理类代理的是一个接口一般就是对应的一类业务。一个动态代理类可以代理多个类只要是实现了同一个接口即可!
10、AOP
10.1、什么是AOP
AOP (Aspect Oriented Programming)意为: 面向切面编程通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续是软件开发中的一个热点也是Spring框架中的一个重要内容是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离从而使得业务逻辑各部分之间的耦合度降低提高程序的可重用性同时提高了开发的效率。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sG68kfs5-1620196766100)(C:\Users\17728\AppData\Roaming\Typora\typora-user-images\image-20210504213617773.png)]
10.2 、Aop在Spring中的作用
提供声明式事务;允许用户自定义切面。
横切关注点:跨越应用程序多个模块的方法或功能。即是与我们业务逻辑无关的但是我们需要关注的部分就是横切关注点。如日志安全缓存事务等等…切面(ASPECT)︰横切关注点被模块化的特殊对象。即它是一个类。通知(Advice) :切面必须要完成的工作。即它是类中的一个方法。目标(Target)︰被通知对象。代理Proxy)∶向目标对象应用通知之后创建的对象。切入点PointCut):切面通知执行的“地点的定义。连接点(JointPoint):与切入点匹配的执行点。
SpringAOP中通过Advice定义横切逻辑Spring中支持5种类型的Advice:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Hdm9vfF-1620196766101)(C:\Users\17728\AppData\Roaming\Typora\typora-user-images\image-20210504215028586.png)]
即Aop在不改变原有代码的情况下去增加新的功能
10.3、使用Spring实现Aop【重点】
使用AOP织入需要导入一个依赖包!
!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --
dependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.9.5/version
/dependency
注册bean !--注册bean--bean iduserService classcom.nynu.qdy.service.UserServiceImpl/bean idlog classcom.nynu.qdy.log.Log/bean idafterLog classcom.nynu.qdy.log.AfterLog/方式一 使用Spring的接口 【主要是SpringAPI接口实现】
!--方式一使用原生Spring API接口--
!--配置aop需要导入aop的约束--aop:config!--切入点 expression :表达式 execution:要执行的位置--aop:pointcut idpointcut expressionexecution(* com.nynu.qdy.service.UserServiceImpl.*(..))/!--执行环绕增加--aop:advisor advice-reflog pointcut-refpointcut/aop:advisor advice-refafterLog pointcut-refpointcut//aop:config方式二 自定义类实现AOP (XML)【主要是切面定义】 !--方式二基于xml的声明式AspectJ--bean iddiy classcom.nynu.qdy.diy.DiyPointCut/aop:config!-- 自定义切面 ref:要引用的类--aop:aspect refdiy!--切入点--aop:pointcut idpointcut expressionexecution(* com.nynu.qdy.service.UserServiceImpl.*(..))/!--配置通知--!--前置通知--aop:before methodbefore pointcut-refpointcut/!--后置通知--aop:after methodafter pointcut-refpointcut/!--环绕通知--aop:around methodaround pointcut-refpointcut/!--异常通知--aop:after-throwing methodafterThrowing pointcut-refpointcut throwingthrowable/!--最终通知--aop:after-returning methodafterReturning pointcut-refpointcut//aop:aspect/aop:config方式三 使用注解实现
!--方式三基于注解的声明式AspectJ--bean idannotationPointCut classcom.nynu.qdy.diy.AnnotationPointCut/!--开启注解支持 jdk(默认proxy-target-classfalse) cglib(proxy-target-classtrue)--aop:aspectj-autoproxy proxy-target-classtrue/
xml
ointcut expressionexecution(* com.nynu.qdy.service.UserServiceImpl.*(..))/!--配置通知--!--前置通知--aop:before methodbefore pointcut-refpointcut/!--后置通知--aop:after methodafter pointcut-refpointcut/!--环绕通知--aop:around methodaround pointcut-refpointcut/!--异常通知--aop:after-throwing methodafterThrowing pointcut-refpointcut throwingthrowable/!--最终通知--aop:after-returning methodafterReturning pointcut-refpointcut//aop:aspect/aop:config方式三 使用注解实现
!--方式三基于注解的声明式AspectJ--bean idannotationPointCut classcom.nynu.qdy.diy.AnnotationPointCut/!--开启注解支持 jdk(默认proxy-target-classfalse) cglib(proxy-target-classtrue)--aop:aspectj-autoproxy proxy-target-classtrue/