spring笔记(精简版)

Spring的核心是控制反转(IoC)和面向切面(AOP)

IoC

具体面试示例:

大佬:我看你用过这个Spring啊,你来聊聊为什么我们要使用Spring呢?

我:(因为大家都说好啊)首先呢,spring是一个庞大的容器,它封装了很多成熟的功能能够让我们无需重复造轮子。
其次呢,它使用IOC进行依赖管理,我们就不用自己初始化实例啦。

大佬:(我就知道你会说IOC啦)那你解释一下IOC吧

我:Spring是个大容器,存放着各种各样的bean,以往这些bean是你自己主动去new出来的。有了spring后,所有的bean是spring容器通过反射机制来进行获取,因此控制权就由你自己反转到了spring容器上。

大佬:那我们可以直接使用工厂模式呀。工厂模式也可以管理实例的初始化呀,为什么一定要使用Spring呢?

这里查了一下为什么不用工厂模式而使用IOC。其实本质上还是因为IOC是通过反射机制来实现的。
当我们的需求出现变动时,工厂模式需要进行相应的变化。但是IOC的反射机制使得对象是动态生成的,
因此我们不需要重新编译代码。
  1. IoC的使用方式:
    ① 将所有的bean都配置xml中:<bean id="" class="">
    ② 将所有的依赖都使用注解:@Autowired
    需要对bean使用@Component,以及在xml中配置扫描器<context:component-scan base-package=" ">

  2. IOC的原理(工厂模式+反射技术)
    3.1 IOC容器的初始化过程(bean的注册):
    (1)xml读取,解析成beanDefinition,最后在beanFactory中进行注册。
    在这里插入图片描述
    在这里插入图片描述
    (2)注册:Spring容器内部有一个HashMap ,存放着bean的信息,以后对 bean 的操作都是围绕这个HashMap 来实现的。在这里插入图片描述
    3.2 依赖注入
    当Spring IoC容器完成了初始化后,IoC容器中已经管理类Bean定义的相关数据,但是此时IoC容器还没有对所管理的Bean进行依赖注入,在spring IOC设计中,bean的注册和依赖注入是两个过程,依赖注入在以下两种情况发生:
    a.用户第一次通过getBean方法向IoC容器索要Bean时,IoC容器触发依赖注入。
    b.当用户在Bean定义资源中为元素配置了lazy-init属性,即让容器在解析注册Bean定义时进行预实例化,触发依赖注入。

beanFactory和factoryBean:
  1. BeanFactory:就是生产bean的工厂,用于生成任意bean。
  2. FactoryBean:特殊bean,用于生成特定的bean。FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,这样便可以在getObject()方法中对要生成的bean进行灵活配置,比方说生成bean的前后都可以加入一些代码。

在spring配置文件中配置了名字 myFcBean 的一个类型,该类型是 FactoryBean 的实现类。那么通过
BeanFactory.getBean(“myFcBean”) 返回的并不是这个类型本身的对象,而是调用这个对象的getObject方法的返回值。

需要注意的是:getBean(“factoryBean”); 返回的不是这个工厂bean,而是它生产的具体bean
使用:比方说在生成前加一段话。

public class ProductFactory implements FactoryBean<Object> {
	...
	    @Override
    public Object getObject() throws Exception {
        logger.debug("getObject......");
        return new Product();
    }

    @Override
    public Class<?> getObjectType() {
        return Product.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
	...
}

配置:

 <bean id="ProductFactory" class="com.xxx.ProductFactory"/> 

AOP:

  1. 好处:降低耦合度、代码复用

  2. 采取横向抽取机制,取代了传统纵向继承

  3. 一句话:个人理解,aop就是使用代理机制,,对目标类的切入点进行增强。

  4. 代理机制有jdk动态代理和cglib增强两种

  5. AOP术语【掌握】
    1.target:目标类,需要被代理的类。例如:UserService
    2.Joinpoint(连接点):所谓连接点是指那些可能被拦截到的方法。例如:所有的方法
    3.PointCut 切入点:已经被增强的连接点。例如:addUser()
    4.advice 通知/增强,增强代码。例如:after、before
    5.Weaving(织入):是指把增强advice应用到目标对象target来创建新的代理对象proxy的过程.
    6.proxy 代理类
    7.Aspect(切面): 是切入点pointcut和通知advice的结合
    一个线是一个特殊的面。
    一个切入点和一个通知,组成成一个特殊的面。
    在这里插入图片描述

  6. AOP的两种实现方式:基于配置的(xml)和基于注释(AspectJ)
    基于配置:定义接口和实现类 -> 定义切面 -> xml配置目标类、切面和aop:config

目标类(接口和实现类)

public interface UserService{
    public void addUser();
}

public class UserServiceImpl implements UserService{
    @Override
    public void addUser() {
        System.out.println("addUser! ");
    }
}

切面类:

public class MyAspect implements MethodInterceptor {
	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		
		System.out.println("前3");
		//手动执行目标方法
		Object obj = mi.proceed();
		System.out.println("后3");
		return obj;
	}
}

xml配置(需要添加schema):

<?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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       					   http://www.springframework.org/schema/beans/spring-beans.xsd
       					   http://www.springframework.org/schema/aop 
       					   http://www.springframework.org/schema/aop/spring-aop.xsd">
	<!-- 1 创建目标类 -->
	<bean id="userServiceId" class="com.itheima.c_spring_aop.UserServiceImpl"></bean>
	<!-- 2 创建切面类(通知) -->
	<bean id="myAspectId" class="com.itheima.c_spring_aop.MyAspect"></bean>
	<!-- 3 aop编程 
		3.1 导入命名空间
		3.2 使用 <aop:config>进行配置
				proxy-target-class="true" 声明时使用cglib代理
			<aop:pointcut> 切入点 ,从目标对象获得具体方法
			<aop:advisor> 特殊的切面,只有一个通知 和 一个切入点
				advice-ref 通知引用
				pointcut-ref 切入点引用
		3.3 切入点表达式
			execution(* com.itheima.c_spring_aop.*.*(..))
			选择方法         返回值任意   包             类名任意   方法名任意   参数任意
		
	-->
	<aop:config proxy-target-class="true">
		<aop:pointcut expression="execution(* com.itheima.c_spring_aop.*.*(..))" id="myPointCut"/>
		<aop:advisor advice-ref="myAspectId" pointcut-ref="myPointCut"/>
	</aop:config>
</beans>

基于注释:定义接口和实现类 -> 定义切面:使用@Aspect,并直接在类中定义切入点和增强

@Component
@Aspect
public class Operator {
    
    @Pointcut("execution(* com.aijava.springcode.service..*.*(..))")
    public void pointCut(){}
    
    @Before("pointCut()")
    public void doBefore(JoinPoint joinPoint){
        System.out.println("AOP Before Advice...");
    }
    
    @After("pointCut()")
    public void doAfter(JoinPoint joinPoint){
        System.out.println("AOP After Advice...");
    }
    
    @AfterReturning(pointcut="pointCut()",returning="returnVal")
    public void afterReturn(JoinPoint joinPoint,Object returnVal){
        System.out.println("AOP AfterReturning Advice:" + returnVal);
    }
    
    @AfterThrowing(pointcut="pointCut()",throwing="error")
    public void afterThrowing(JoinPoint joinPoint,Throwable error){
        System.out.println("AOP AfterThrowing Advice..." + error);
        System.out.println("AfterThrowing...");
    }
    
    @Around("pointCut()")
    public void around(ProceedingJoinPoint pjp){
        System.out.println("AOP Aronud before...");
        try {
            pjp.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("AOP Aronud after...");
    }
    
}
  1. 通知类型:
    前置通知(Before advice):在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
    后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
    环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。
    异常通知(After throwing advice):在方法抛出异常退出时执行的通知。
    最终通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。

AOP之事物(了解):

  1. 一个事务过程中只会有一个Connetion对象!

  2. 事务的传播属性(一般选择Required,读操作选择Supports
    在这里插入图片描述

  3. 使用(对service层进行aop增强)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	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-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!-- 事务配置 -->
	<!-- 事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<!-- 数据源 -->
		<property name="dataSource" ref="dataSource" />
	</bean>
	<!-- 通知 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 传播行为 -->
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="insert*" propagation="REQUIRED" />
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="create*" propagation="REQUIRED" />
			<tx:method name="delete*" propagation="REQUIRED" />
			<tx:method name="update*" propagation="REQUIRED" />
			<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="select*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
		</tx:attributes>
	</tx:advice>
	<!-- 切面 -->
	<aop:config>
		<aop:advisor advice-ref="txAdvice"
			pointcut="execution(* com.YYSchedule.store.service.*.*(..))" />
	</aop:config>
</beans>
Springmvc

主要流程是:
处理器映射器(请求查找handler) --> 处理器适配器(执行action,返回modelandview) --> 试图解析器(解析成view) --> view层(渲染) -->用户
在这里插入图片描述
添加链接描述https://www.cnblogs.com/Java-Starter/p/10475374.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值