【Spring】Spring全面详解(二)--什么是spring spring的三大核心概念?(超详细建议收藏慢慢看)

本文详细介绍了Spring中的AOP概念,包括前置、后置、异常和环绕通知的实际应用,并探讨了解决方案。接着讨论了Spring与MyBatis的集成,包括整合、优化、事务处理和版本锁定。最后,重点讲解了Spring事务的配置优化,包括声明式和注解事务的两种常见方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring


第四章

1、aop
2、spring与mybatis集成
3、spring中的事务处理

1、Aop—面向切面编程

通知类型
	1、前置通知: 它是在业务逻辑代码执行之前由系统自动调用

	2、后置通知: 它是在业务逻辑代码执行之后由系统自动调用

	3、异常通知: 它是在业务逻辑代码执行过程中,产生异常时由系统自动调用
				(它与后置通知属于平级关系,二者只执行其一)				

	4、环绕通知: 它相当于前置+后置通知,它会把业务代码的执行过程包含在通知中
1、前置通知
	特点:前置通知中的代码,将会自动在业务逻辑代码之前自动调用
	前置通知的要求:

		1、通知类需要实现接口MethodBeforeAdvice
			public class BeforeAdvice implements MethodBeforeAdvice {
   }
		
		2、重写接口的before方法
			public void before(Method method, Object[] args, Object targetClass) throws Throwable {
   }
2、后置通知
	特点:前置通知中的代码,将会自动在业务逻辑代码之后自动调用
	后置通知的要求:

		1、通知类需要实现接口AfterReturningAdvice
			public class AfterAdvice implements AfterReturningAdvice {
   }

		2、重写接口的afterReturning方法
			public void afterReturning(Object returnValue, Method method, Object[] args, Object targetClass) throws Throwable {
   }

//后置通知多了一个参数(返回的数据)
3、异常通知

(异常通知与后置通知属于平级,二者只会触发一个)

	特点:异常通知中的代码,它会在业务逻辑类执行过程中产生异常时自动调用(其他类产生的异常,异常通知并不触发)
		异常通知的要求:
	
		1、通知类需要实现接口ThrowsAdvice
		注意:这个接口比较特殊,接口中并没有方法,它是一个标识性接口,标识当前是一个异常通知
			public class MyThrowsAdvice implements ThrowsAdvice {
   
			}
			
		2、编写方法(格式不能随便写)
			public void afterThrowing(Method method, Object[] args, Object targetClass,Exception ex){
   
			
			}

【实际应用】

	1、编写MyThrowsAdvice类实现ThrowsAdvice接口
    
    2、编写方法afterThrowing
    	    public void afterThrowing(Method method, Object[] args, Object targetClass, Exception ex){
   

        System.out.println("---------------------进入异常通知--------------------");
        System.out.println("产生异常的业务逻辑类:"+targetClass.getClass());
        System.out.println("产生异常的方法:"+method.getName());
        System.out.println("产生异常的原因:"+ex.getMessage());
        System.out.println("---------------------离开异常通知--------------------");
    }
	
	3、注册后置通知
    <!--注册异常通知-->
    <bean id="throws" class="org.java.advice.myThrowsAdvice"/>
        
    4、在代理模式中配置异常
        <!-- 2、代理附加的额外功能-->
        <property name="interceptorNames">
            <list>
                <value>before</value>
                <value>after</value>
                <value>throws</value>
            </list>
        </property>

image-20230616170451868

4、环绕通知
特点:环绕通知是把业务逻辑代码运行的整个过程,包含在通知中

	环绕通知的要求:
		1、通知类需要实现接口 MethodInterceptor
			public class RoundAdvice implements MethodInterceptor {
   
			
			}
			
		2、重写接口的方法
		    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
   
			return null;
		    }

【实际应用】

1、编写RoundAdvice类实现MethodInterceptor接口

2、重写接口的方法invoke

	@Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
   
        System.out.println();
        System.out.println("--------------------进入环绕通知-----------------------");
        System.out.println("即将访问的业务类:"+methodInvocation.getThis().getClass());
        System.out.println("即将访问的业务方法:"+methodInvocation.getMethod().getName());
        System.out.println("即将传递的参数:"+ Arrays.toString(methodInvocation.getArguments()));
        System.out.println("--------------------准备离开环绕通知,进入业务逻辑类-------");
        System.out.println();
        //此方法执行后,就会进入业务类逻辑类,返回的obj即为业务方法发返回结果
        Object obj = methodInvocation.proceed();
        System.out.println();
        System.out.println("--------------------回到环绕通知,继续环绕-----------------------");
        System.out.println("业务类返回的结果是:"+obj);

        System.out.println("--------------------离开环绕通知-----------------------");
        return obj;

    }

3、注册后置通知
    <!--注册环绕通知-->
    <bean id="round" class="org.java.advice.roundAdvice"/>

4、在代理模式中配置环绕通知

	//由于环绕通知就是前置通知+后置通知,因此,在附加功能上只需要配置环绕通知即可
	
	    <!--配置代理-->
    <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!--  1、指定代理的业务接口-->
        <property name="proxyInterfaces">
            <value>org.java.service.buyBookService</value>
        </property>
        <!-- 2、代理附加的额外功能-->
        <property name="interceptorNames">
            <list>
                <value>throws</value>
                <value>round</value>
            </list>
        </property>
        <!--3、功能附加完成后要访问的业务类-->
        <property name="target" ref="buyBookService"/>
    </bean>

目前存在的问题
【问题】:
1、当前代理类只能对1个业务类进行代理,如果有1000个业务类,就需要配置1000个代理类
2、配置了代理类以后,只有访问代理类才能附加功能,如果直接访问业务类的名称,AOP的功能无法附加
解决方案
【解决方案1:配置自动代理】
特点:
		1、不用单独的配置代理,系统会根据访问的业务类的名称自动生成代理 
		2、访问时,直接访问业务类的名称即可,不用访问代理的名称 
缺点:
		value里面的业务类还是需要写一千次
		
	a、在applicationContext.xml文件配置自动代理 
	 <!--    配置自动代理-->
		    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
			<!--1、指定访问哪些业务类的时候,自动创建代理-->
			<property name="beanNames">
			    <list>
				<value>buyBookService</value>
				<value>buyBookService2</value>
				<value>buyBookService3</value>
			    </list>
			</property>
			<!--2、指定要代理要附加的功能-->
			<property name="interceptorNames">
			    <list>
				<value>before</value>
				<value>after</value>
				<value>mythrows</value>
			    </list>
			</property>
		    </bean>

	b、访问时,直接访问业务类的名称即可,不用访问代理类
		BuyBookService bookService = (BuyBookService) cxt.getBean("buyBookService");
【解决方案2:配置声明式代理】
 @@@特点:对指定包下面的所有业务类自动形成代理 

	 1、编写通知类(注意:这种通知类不需要实现任何接口)
		 public class MyAdvice {
   

		    /**
		     * 前置通知
		     * JoinPoint:通过它可以获得当前要访问的业务类的名称 ,方法名,参数
		     */
		    public void before(JoinPoint joinPoint){
   
			System.out.println("-------进入前置通知------------");
			System.out.println("即将访问的业务类是:"+joinPoint.getTarget().getClass());
			System.out.println("即将访问的业务方法:"+joinPoint.getSignature().getName());
			System.out.println("传递的参数有:"+ Arrays.toString(joinPoint.getArgs()));
			System.out.println("-------离开前置通知------------");

		    }
             
              //后置通知类
    public void after(JoinPoint joinPoint, Object obj) {
   //obj:返回值
        System.out.println();
        System.out.println("------------进入后置通知--------------------------");
        System.out.println("访问的业务逻辑类:" + joinPoint.getTarget().getClass());
        System.out.println("调用业务逻辑类中的哪一个方法:" + joinPoint.getSignature().getClass());
        System.out.println("传递给方法的参数:" + Arrays.toString(joinPoint.getArgs
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

arjunna

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值