Spring(二)

AOP: 面向切面编程

通常,系统由很多组件组成,每个组件负责一部分功能,然而,这些组件也经常带有一些除了核心功能之外的附带功能 。系统服务如日志、事务管理和安全经常融入到一些其他功能模块中。这些系统服务通常叫做交叉业务
AOP能帮助我们将服务模块化,并把它们声明式地应用在需要它们的地方,使得这些组件更加专注于自身业务,完全不知道其它涉及到的系统服务。
这里的概念切面,就是我们要实现的交叉功能,是应用系统模块化的一个方面或领域。切面的最常见例子就是日志记录。日志记录在系统中到处需要用到,利用继承来重用日志模块是不合适的,这样,就可以创建一个日志记录切面,并且使用AOP在系统中应用。

有些代码与业务无关,却被业务模块所调用并封装起,Spring提供了面向切面的编程方式,即SpingAOP,来解决这个问题,能有效的减少了系统间的重复代码,达到了模块间的松耦合目的。

AOP采用横向抽取机制,取代了传统纵向继承体系重复性代码,主要体现在事务处理,日志管理,权限控制,异常处理等方面,使开发人员在编写业务逻辑时可以专心于核心业务,提高了代码的可维护性。

AOP框架

目前最流行的AOP框架有两个,分别为Spring AOP 和AspectJ.
Spring AOP使用纯Java实现,不需要专门的编译器。
AspectJ 是一个基于java语言的AOP框架,并对AspectJ进行了扩展,提供了一个专门的编译器

新版本Spring框架,建议使用AspectJ方式来开发AOP。

配置文件的头信息

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

</beans>

增加了AOP的命名空间与AOP的xsd规范,如不需要注解,可以省略context.xsd
就是其黄色的部分。用于注解。

通知类型

前置通知:在目标方法执行前执行
后置通知:在目标方法执行后执行
异常通知:在目标方法抛出异常后执行
环绕通知:在目标方法执行前和后执行

切面程序:后置通知的切面程序中可以获取到目标方法返回参数,但需要在配置文件中声明参数名,依赖spring容器注入参数值。

后置通知

切入点程序:

package model;

public class Chengxu {
	
	public String talk(String str){
		
		System.out.println("str="+str);
         return "保存成功";
	}

}

切面程序:

package model;

import org.aspectj.lang.JoinPoint;

public class Charu {
	
	public void log(JoinPoint jp,Object ret){
		
		System.out.println("后置");
		System.out.println("obj为目标组件方法返回值:" +ret);
		
	}
}

如果没有返回值,这里的Object要去掉,否则报错

public void log(JoinPoint jp,Object obj){
		
		System.out.println("log......");
		System.out.println("获取目标函数参数方式:" +jp.getArgs()[0]);
		System.out.println("获取目标对象:" +jp.getTarget().getClass().getName());
		System.out.println("获取目标函数的java反射对象:" +jp.getSignature());
		
		System.out.println("返回值===="+obj);
	}

测试类:

package model;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestChengxu {
	
	@Test
	public void test(){
		
		ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("model/applicationContext.xml");
		Chengxu chengxu = (Chengxu)app.getBean("chengxu");
		
		chengxu.talk("聊天");
		
		
	}

异常通知

异常通知:在目标组件的方法抛出异常信息后执行的程序。
当前置通知和后置通知发生异常时,这个异常通知是不执行的,只有当目标组件发生异常时才执行。

切面程序:异常通知的切面程序中可以获取到目标组件抛出的异常信息,需要在配置文件上声明异常参数名,依赖spring容器注入参数值。

最终通知

最终通知:在目标组件的方法正常执行后执行,或在异常通知之前执行。
也就是当目标组件发生没发生异常,都会被执行。
如果目标组件异常时,那后置通知不会执行,异常通知会执行。最终通知会在异常通知之前执行。
如果目标组件正常时,那最终通知会在后置通知之前执行。

切面程序:异常通知的切面程序中可以获取到目标组件抛出的异常信息,需要在配置文件上声明异常参数名,依赖spring容器注入参数值。

Application.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
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
        
	<!--切入点程序 -->
	<bean id="chengxu" class="model.Chengxu"></bean>
	<!--切面程序 前置-->
	<bean id="charu" class="model.Charu"></bean>
	<!--切面程序2 后置-->
	<bean id="charu2" class="model.Charu2"></bean>
	<!--切面程序3 异常-->
	<bean id="charu3" class="model.Charu3"></bean>
	<!--切面程序4 最终-->
	<bean id="charu4" class="model.Charu4"></bean>
	
	<!-- AOP配置跟标签 -->
	<aop:config>
		<!-- 切入点配置:expression切入点表达式   * model....不限返回类型  (*)方法里面是什么参数类型都可以,方法没有参数也可以那就不加这个* 
		   -->
		<aop:pointcut expression="execution(* model.Chengxu.talk(*))" id="chengxuPointCut"/>
		
		<!-- 切面配置 -->
		<!-- aspect切面程序依赖于谁 -->
		<aop:aspect ref="charu"> 
			<!-- 前置通知 -->
		<!--切面程序的方法 切入点依赖于谁  (简单的说,把这个方法前置在哪个方法前面) -->
			<aop:before method="log" pointcut-ref="chengxuPointCut"/>
		</aop:aspect>
		
		
		<aop:aspect ref="charu2"> 
		<!-- 后置通知 -->
		<!--切面程序的方法 切入点依赖于谁  (简单的说,把这个方法前置在哪个方法后面) -->
			<aop:after-returning method="log2" pointcut-ref="chengxuPointCut"
			returning="ret"/>
		</aop:aspect>
		
		<aop:aspect ref="charu3"> 
		<!-- 异常通知 -->
		<!--切面程序的方法 切入点依赖于谁  (简单的说,当目标组件发生异常时,执行log3个这方法) -->
			<aop:after-throwing method="log3" pointcut-ref="chengxuPointCut"
			throwing="t"/>
		</aop:aspect>
		
		<aop:aspect ref="charu4"> 
		<!-- 最终通知 -->
		<!--切面程序的方法 切入点依赖于谁  (简单的说,目标组件无论发生不发生异常都会走这个log4方法) -->
			<aop:after method="log4" pointcut-ref="chengxuPointCut"/>
		</aop:aspect>
		
		
		
	</aop:config>
	
	
</beans>

环绕通知

环绕通知: 切面程序负责调用目标组件的运行,与struts中的拦截器功能类似,可以完全取代之前的几个通知。

切面程序:在类型为环绕通知的切面程序函数中,参数为org.aspectj.lang.ProceedingJoinPoint是JoinPoint的子类,扩展了JoinPoint类,提供了proceed()函数,该函数的作用是调用目标组件,并返回目标组件返回的值。

<!-- AOP配置跟标签 -->
	<aop:config>
	<!-- 切入点配置:expression切入点表达式   * model....不限返回类型  (*)方法里面是什么参数类型都可以,方法没有参数也可以那就不加这个* 
		   -->
		<aop:pointcut expression="execution(* model.Chengxu.talk(*))" id="chengxuPointCut"/>
		
		

		<aop:aspect ref="charu5"> 
			<!-- 环绕通知 -->
			<aop:around method="log5" pointcut-ref="chengxuPointCut"/>
		</aop:aspect>
	</aop:config>
</beans>

切面程序:

package model;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class Charu5 {
	
	public void log5(ProceedingJoinPoint pjp) {
		System.out.println("前置通知");
		try {
			Object ob = pjp.proceed();
			System.out.println("目标函数的返回值:"+ob);
			System.out.println("后置通知");
		} catch (Throwable e) {
			System.out.println("异常通知");
		}
		System.out.println("最终通知");
	}

public void log5(ProceedingJoinPoint pjp) {

		System.out.println("环绕通知开始");
		
Object ob = pjp.proceed();
			
		System.out.println("环绕通知结束");
	}

切入点表达式

切入点表达式: 切入点表达式用于声明spring容器中哪些组件的函数是目标函数,也就是切面程序要作用到哪些组件的哪些函数上。

常用的切入点表达式分为:
1)按类匹配:匹配的java类中全部函数作为目标函数使用within关键字。
2)按函数匹配:匹配的函数作为目标函数,使用execution关键字。
3)按bean的id匹配:匹配的bean中全部函数作为目标组件。使用bean关键字

按类匹配:

匹配到类

<aop:pointcut id="targetPintcut"
                expression="within(com.chinasofti.Target)"/>
匹配到包下的类
 <aop:pointcut id="targetPintcut"
                expression="within(com.chinasofti.*)"/>
匹配到包下及子包下的类	
<aop:pointcut id="targetPintcut"
                expression="within(com..*)"/>

按函数匹配:
完整写法
返回类型 类的路径 类名 函数名 参数类型(用,分开)
execution(String com.chinasofti.Target.save(String))
任意返回类型
execution(* com.chinasofti.Target.save(String))
任意返回类型下指定包下任意类
execution(* com.chinasofti..save(String))
任意返回类型下指定包下任意类任意函数
execution(
com.chinasofti..(String))
任意返回类型下指定包或子包下任意类任意函数任意参数
execution(* com….(…))

AOP注解

  <!-- 开启自动扫描 -->
     <context:component-scan base-package="com.china.model"></context:component-scan>
    
     <!-- spring中使用aspectj包中的@Aspect注解标注当前组件为切面,
        	如果要使用改注解必须开启aspectj的自动代理模式 -->
     <aop:aspectj-autoproxy ></aop:aspectj-autoproxy>

@Component(“before”)
@Aspect --切面程序
@Before(value=“execution(* com.china.model.Chengxu.talk())") --前置通知
@AfterReturning(value=“execution(com.china.model.Chengxu.talk())”,returning=“ret”) --后置通知
@AfterThrowing(value="execution(
com.china.model.Chengxu.talk())", throwing=“e”) --异常通知
@After(value="execution(
com.china.model.Chengxu.talk())") --最终通知
@Around(value="execution(
com.china.model.Chengxu.talk(*))”) --环绕通知

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值