Spring5

官方文档:https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/spring-framework-reference/index.html

zip下载地址:https://repo.spring.io/release/org/springframework/spring/5.2.6.RELEASE/

bean注入:

无参构造 (set注入 多种方式https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/spring-framework-reference/core.html#beans-setter-injection)

classpath下beans.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 使用Spring创建bean -->
<bean id="userDao" class="com.yan.dao.impl.UserDaoImpl">
</bean>
<bean id="userDaoOracle" class="com.yan.dao.impl.UserDaoImplOracle">
</bean>
<bean id="userService" class="com.yan.service.impl.UserServiceImpl">
<!--要有set方法-->
<property name="userDao" ref="userDaoOracle">
</property>
</bean>
</beans>

使用:

		ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService)context.getBean("userService");
userService.getUser();
有参构造 (构造器注入)

下标

	<bean id="hello" class="com.yan.entity.Hello">
<constructor-arg index="0" value="str000">
</constructor-arg>
<constructor-arg index="1" value="1">
</constructor-arg>
</bean>

类型

<bean id="hello" class="com.yan.entity.Hello">
<constructor-arg type="java.lang.String" value="str000">
</constructor-arg>
<constructor-arg type="java.lang.Integer" value="1">
</constructor-arg>
</bean>

参数名

<!-- 参数名   -->
<bean id="hello" class="com.yan.entity.Hello">
<constructor-arg name="str" value="str000">
</constructor-arg>
<constructor-arg name="num" value="1">
</constructor-arg>
</bean>

bean引用

 <bean id="str" class="java.lang.String">
<constructor-arg type="java.lang.String" value="str000">
</constructor-arg>
</bean>
<bean id="num" class="java.lang.Integer">
<constructor-arg type="int" value="1">
</constructor-arg>
</bean>
<bean id="hello" class="com.yan.entity.Hello">
<constructor-arg name="str" ref="str">
</constructor-arg>
<constructor-arg name="num" ref="num">
</constructor-arg>
</bean>

构造函数声明:

public Hello(String str,Integer num)

合并配置文件

applicationContext.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="beans.xml"/>
<import resource="beans2.xml"/>
</beans>

bean作用域

配置方法:bean的scope属性

 <bean id="hello" class="com.yan.entity.Hello" scope="prototype">
<constructor-arg name="str" ref="str">
</constructor-arg>
<constructor-arg name="num" ref="num">
</constructor-arg>
</bean>

可选值:

singleton 单例(默认)

prototype 多例

request

session

application

websocket

自动装配bean

xml (byName,byType)

byName:要求id全局唯一并且和要注入的属性的变量名一致

byType: 要求此类型实例全局唯一并且和要注入的属性类型一致

	<bean id="dog" class="com.yan.entity.Dog">
</bean>
<bean id="cat" class="com.yan.entity.Cat">
</bean>
<bean id="people" class="com.yan.entity.People" autowire="byName">
</bean>

java代码

注解

额外配置:

导入context命名空间并且开启注解支持:

<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> </beans>

demo

xml配置:

	<context:annotation-config/>
<bean id="dog" class="com.yan.entity.Dog">
</bean>
<bean id="cat" class="com.yan.entity.Cat">
</bean>
<bean id="people" class="com.yan.entity.People">
</bean>

代码中配置(有注入注解可以没用set方法):

public class People {
private String name;
@Autowired
private Dog dog;
@Autowired
private Cat cat;
public Dog getDog() {
return dog;
} public Cat getCat() {
return cat;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

@Autowired默认是byType方式注入的,类型不唯一byName

@Resource 默认是byName方式注入的,名字不唯一byType,是java原生注解可以实现和@Autowired类似的功能

注解开发

配置文件

<?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
https://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="com.yan.annotation"/>
<!-- 开启注解支持-->
<context:annotation-config/>
</beans>

bean IOC:

模式注解:@Component,@Controller,@Service,@Repository,@Mapper,@SpringBootApplication...

属性注入:

@Autowried,@Value

全面使用注解(java config方式)

配置类

@Configuration
public class Config {
@Bean
public User user(){
return new User();
}
}

使用

public class MyTest {
public static void main(String[] args) {
ApplicationContext context=new AnnotationConfigApplicationContext(Config.class);
User user = (User) context.getBean("user");
}
}

@Configuration用于标注一个配置类,可以和@ComponentScans,@Import等注解完成诸如扫描包,合并配置文件等功能

AOP

静态代理

真实类:房东

public class Host implements Rent {
@Override
public void rent() {
System.out.println("我是房东,我要出租房子");
}
}

代理类:租房中介

public class Proxy implements Rent {
private Rent host;
@Override
public void rent() {
System.out.println("先发布租房信息");
host.rent();
System.out.println("出租完房子提供后续管理");
} public void setHost(Rent host) {
this.host = host;
}
}

接口:出租

public interface Rent {
void rent();
}

客户类:房客

public class Client{
public static void main(String[] args) {
Host host=new Host();
Proxy proxy=new Proxy();
proxy.setHost(host);
proxy.rent();
}
}

缺点:每个代理方法的都要手动处理代理逻辑,每个接口都要有新的代理类,冗余代码多

动态代理

动态代理的代理类是动态生成的

基于接口

jdk动态代理

Proxy 获取代理对象

InvocationHandler 调用处理程序

接口:

public interface Rent {
void rent();
}

真实类:

public class Host implements Rent {
@Override
public void rent() {
System.out.println("我是房东,我要出租房子");
}
}

代理处理类

//这个类动态生成代理类,并用invoke方法调用原来方法,可以在其中添加代理逻辑
public class ProxyInvocationHandler implements InvocationHandler {
private Rent rent; public void setHost(Rent rent) {
this.rent = rent;
} //动态生成代理类
public Rent getProxy(){
Rent proxyInstance = (Rent) Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
return proxyInstance;
}
//处理代理实例并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(rent, args);
return result;
}
}

客户类

public class Client {
public static void main(String[] args) {
ProxyInvocationHandler pih=new ProxyInvocationHandler();
pih.setHost(new Host());
Rent proxy = pih.getProxy();
proxy.rent();
}
}

通用代理工具类:

//通用代理类
//这个类动态生成代理类,并用invoke方法调用原来方法,可以在其中添加代理逻辑
public class CommonProxyInvocationHandler implements InvocationHandler {
private Object realObject; public void setRealObject(Object realObject) {
this.realObject = realObject;
} //动态生成代理类
public Object getProxy(){
Object proxyInstance = Proxy.newProxyInstance(this.getClass().getClassLoader(), realObject.getClass().getInterfaces(), this);
return proxyInstance;
}
//处理代理实例并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法执行前");
Object result = method.invoke(realObject, args);
System.out.println("方法执行后");
return result;
}
}

匿名类实现

//用匿名类实现
Object realObject= new Host();
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName()+"执行前");
Object result = method.invoke(realObject, args);
System.out.println(method.getName()+"执行后");
return result;
}
};
Object proxyInstance = Proxy.newProxyInstance(Client.class.getClassLoader(), realObject.getClass().getInterfaces(), invocationHandler);
((Rent)proxyInstance).rent();

优点:一个动态代理类可以处理一类代理业务

基于类

cglib动态代理

基于 java字节码

javasist

AspectJ

使用Spring实现aop

Spring代理实际上是对JDK代理和CGLIB代理做了一层封装,并且引入了AOP概念:Aspect、advice、joinpoint等等,同时引入了AspectJ中的一些注解@pointCut,@after,@before等等.Spring Aop严格的来说都是动态代理,所以实际上Spring代理和Aspectj的关系并不大.(Aspectj有其自己的操作方法-->特殊编译方式在生成字节码阶段织入)

使用实现Spring原生Api+xml配置方式(Spring默认使用 JDK 动态代理)

增强代码

前置增强

public class BeforeExec implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.err.println(method.getName()+"执行前");
}
}

后置增强

public class AfterExec implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.err.println(method.getName()+"执行后"+" 返回值是:"+returnValue);
}
}

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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.yan.aop.service.impl.UserServiceImpl"/>
<bean id="beforeLog" class="com.yan.aop.log.BeforeExec"/>
<bean id="afterExec" class="com.yan.aop.log.AfterExec"/>
<!--配置aop-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="pointcut" expression="execution(* com.yan.aop.service.impl.*.*(..))"/>
<!-- 配置增强-->
<aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterExec" pointcut-ref="pointcut"/>
</aop:config>
</beans>

使用自定义切面类和切面配置切入

切面类

public class AspectLog {
public void before(){
System.out.println("方法执行前");
}
public void after(){
System.out.println("方法执行后");
}
}

配置文件:

<bean id="userService" class="com.yan.aop.service.impl.UserServiceImpl"/>
<bean id="aspect" class="com.yan.aop.log.AspectLog"/>
<aop:config>
<aop:aspect ref="aspect">
<aop:pointcut id="point" expression="execution(* com.yan.aop.service.impl.*.*(..))"/>
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>

这种方法无法获取真实类的一些信息

注解切入

切面类

@Aspect
public class AnnotationLog {
//切入点的注解
@Pointcut(value="execution(* com.yan.aop.service.impl.*.*(..))")
private void pointcut(){}
@Before("execution(* com.yan.aop.service.impl.*.*(..))")
public void before(JoinPoint joinPoint){
// System.out.println(joinPoint.getSignature());
System.out.println("前置通知--->before");
}
@After("AnnotationLog.pointcut()")
public void after(JoinPoint joinPoint){
// System.out.println(joinPoint.getSignature());
System.out.println("后置通知--->after");
}
//最终通知
@AfterReturning(value="AnnotationLog.pointcut()", returning="result")
public void afterReturning(Object result){
System.out.println("后置通知");
}
@Around("AnnotationLog.pointcut()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
//System.out.println("around "+joinPoint.getSignature());
System.out.println("环绕通知前--->around after");
Object proceed = joinPoint.proceed(joinPoint.getArgs());
System.out.println("环绕通知后--->around after");
}
//异常抛出通知
@AfterThrowing(value="AnnotationLog.pointcut()" , throwing="e")
public void find(Throwable e ){
System.out.println("异常抛出通知======"+e.getMessage());
} }

配置:

<bean id="userService" class="com.yan.aop.service.impl.UserServiceImpl"/>
<bean id="annotationAspectLog" class="com.yan.aop.log.AnnotationLog"/>
<!-- true代表开启cglib注解 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>

前后顺序

环绕通知前--->前置通知-->环绕通知后--->后置通知-->最终通知

Spring5学习 (核心)的更多相关文章

  1. iOS学习——核心动画

    iOS学习——核心动画 1.什么是核心动画 Core Animation(核心动画)是一组功能强大.效果华丽的动画API,无论在iOS系统或者在你开发的App中,都有大量应用.核心动画所在的位置如下图 ...

  2. iOS学习——核心动画之Layer基础

    iOS学习——核心动画之Layer基础 1.CALayer是什么? CALayer我们又称它叫做层.在每个UIView内部都有一个layer这样一个属性,UIView之所以能够显示,就是因为它里面有这 ...

  3. spark 入门学习 核心api

    spark入门教程(3)--Spark 核心API开发 原创 2016年04月13日 20:52:28 标签: spark / 分布式 / 大数据 / 教程 / 应用 4999 本教程源于2016年3 ...

  4. spring5学习笔记

    Spring5 框架概述 1.Spring 是轻量级的开源的 JavaEE 框架 2.Spring 可以解决企业应用开发的复杂性 3.Spring 有两个核心部分:IOC 和 Aop (1)IOC:控 ...

  5. ❀ Spring5学习大总结

    一.了解 Spring 基本介绍.主要思想 IoC/DI 1.了解 Spring 基本介绍 (1) Spring是什么? Spring 是一个轻量级的 DI/IoC 和 AOP 容器的开源框架,致力于 ...

  6. Linux学习-核心的编译与安装

    编译核心与核心模块 核心与核心模块需要先编译起来,而编译的过程其实非常简单,你可以先使用『 make help 』去查 阅一下所有可用编译参数, 就会知道有底下这些基本功能: [root@study ...

  7. Linux学习-核心编译的前处理与核心功能选择

    硬件环境检视与核心功能要求 根据自己的需求来确定编译的选项 保持干净原始码: make mrproper 我们还得要处理一下核心原始码底下的残留文件才行!假设我们是第一次 编译, 但是我们不清楚到底下 ...

  8. Linux学习-核心与核心模块

    谈完了整个开机的流程,您应该会知道,在整个开机的过程当中,是否能够成功的驱动我们主机的硬 件配备, 是核心 (kernel) 的工作!而核心一般都是压缩文件,因此在使用核心之前,就得要将他解 压缩后, ...

  9. Spring MVC学习------------核心类与接口

    核心类与接口: 先来了解一下,几个重要的接口与类. 如今不知道他们是干什么的没关系,先混个脸熟,为以后认识他们打个基础. DispatcherServlet   -- 前置控制器 HandlerMap ...

随机推荐

  1. 2021年春软件工程"助教团队"成员介绍

    2021年春软件工程 助教团队 成员介绍 项目 内容 这个作业属于那个课程 2021春季学期软件工程(罗杰.任健) 这个作业的要求在哪里 团队介绍 姓名 照片 个人介绍 分工 刘Q 本团队的PM,和助 ...

  2. C#开发医学影像胶片打印系统(一):万能花式布局的实现思路

    本篇文章将介绍开发医学影像胶片打印系统(printscu模式)遇到不规则排版时的一种思路, 一般来讲,医院打印胶片时都是整张胶片打印,但有时需要将多个病人或一个病人的多个检查打印在同一张胶片上, 这时 ...

  3. 假如kubernetes不支持docker了该怎么办

    假如kubernetes不支持docker了该怎么办 从官网安装文档可以看到kubernetes支持一下几种: https://kubernetes.io/docs/setup/production- ...

  4. 计算机网络-已知IP地址和子网掩码,求广播地址

    首先说结论--广播地址=该IP所在的下一跳-1 例题: 已知IP地址是192.72.20.111,子网掩码是255.255.255.224,求广播地址 要知道下一跳就需要先求出网段间隔,网段间隔=25 ...

  5. (7)MySQL进阶篇SQL优化(InnoDB锁-事务隔离级别 )

    1.概述 在我们在学习InnoDB锁知识点之前,我觉得有必要让大家了解它的背景知识,因为这样才能让我们更系统地学习好它.InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION ...

  6. 858. Mirror Reflection

    There is a special square room with mirrors on each of the four walls.  Except for the southwest cor ...

  7. Libraries

    Math.ceil() The Math.ceil() function returns the smallest integer greater than or equal to a given n ...

  8. 大数翻倍法求解CRT

    目录 正文 引入 大数翻倍法 复杂度证明 大数翻倍法的优势 最后的最后:上代码! 注:做法和思路是 zhx 在一次讲课中提出的,如有侵权,请联系作者删除 其实别的题解也有提到过暴力做法,但这里将会给出 ...

  9. 【接口设计】用户积分排行榜功能-Redis实现

    一.排行榜功能简介 排行榜功能是一个很普遍的需求.使用 Redis 中有序集合(SortedSet)的特性来实现排行榜是又好又快的选择. 一般排行榜都是有实效性的,比如交通数据流中的路口/路段的车流量 ...

  10. 【SpringBoot】Spring Boot

    Spring Boot是由Pribotal团队提供,设计用来简化新Spring应用的初始搭建和开发过程的开源框架. 随着Spring体系越来越庞大,各种配置也是越来越复杂,Spring Boot就是解 ...