汕头正规网站建设模板总部,苏宁易购网站建设的目标,网站备案后内容,网站后台别人制作目录
一、简介
( 1 ) 是什么
( 2 ) 分类
( 3 ) 作用
二、自定义注解
( 1 ) 如何自定义注解
( 2 ) 场景演示
场景一#xff08;获取类与方法上的注解值#xff09;
场景二#xff08; 获取类属性上的注解属性值 #xff09;
场景三#xff08; 获取参数修…目录
一、简介
( 1 ) 是什么
( 2 ) 分类
( 3 ) 作用
二、自定义注解
( 1 ) 如何自定义注解
( 2 ) 场景演示
场景一获取类与方法上的注解值
场景二 获取类属性上的注解属性值
场景三 获取参数修饰注解对应的属性值
三、Aop自定义注解的应用
带给我们的收获 一、简介
( 1 ) 是什么 在Spring MVC中自定义注解是一种通过Java语言提供的元注解机制用于在控制器方法、参数、类等地方添加注解从而实现特定的功能或行为。 在Spring MVC中自定义注解是一种用于标记和定义特定功能的注解。通过自定义注解可以在控制器方法、参数、类等地方添加注解从而实现特定的功能或行为。 Java注解是附加在代码中的一些元信息用于一些工具在编译、运行时进行解析和使用起到说明、配置的功能。 注解相关类都包含在java.lang.annotation包中 通过自定义注解可以提高代码的可读性和可维护性同时也可以减少重复的代码编写。在Spring MVC中可以使用Java的元注解来定义自定义注解例如Target、Retention、Documented等。 通过自定义注解可以提高代码的可读性和可维护性同时也可以减少重复的代码编写。在Spring MVC中自定义注解可以应用于控制器方法的映射、参数校验、数据绑定、AOP切面等方面从而实现特定的功能。 ( 2 ) 分类 Java注解可以分为三类 1. 元注解Meta-Annotation元注解是用来注解其他注解的注解用于对注解进行说明和定义。常用的元注解有四种 - Retention用于指定注解的保留策略即注解在什么地方有效。有三个取值RetentionPolicy.SOURCE注解仅在源代码中有效、RetentionPolicy.CLASS注解在源代码和class文件中有效默认值、RetentionPolicy.RUNTIME注解在运行时有效。- Target用于指定注解的作用目标即注解可以应用在哪些元素上。常用的取值有ElementType.TYPE类、接口、枚举、ElementType.FIELD字段、ElementType.METHOD方法、ElementType.PARAMETER方法参数、ElementType.CONSTRUCTOR构造函数、ElementType.LOCAL_VARIABLE局部变量、ElementType.ANNOTATION_TYPE注解、ElementType.PACKAGE包等。- Documented用于指定注解是否包含在JavaDoc中。- Inherited用于指定注解是否可以被继承。 2. 基本注解Built-in Annotation基本注解是Java内置的一些注解用于标记和修饰代码。常用的基本注解有三个 - Override用于标记方法覆盖父类的方法。- Deprecated用于标记已过时的方法、类或字段。- SuppressWarnings用于抑制编译器警告。 3. 自定义注解Custom Annotation自定义注解是开发者根据业务需求自行定义的注解用于标记和修饰代码。自定义注解可以通过元注解的方式进行配置以达到特定的目的。自定义注解的作用可以是 - 标记和识别特定的代码逻辑或功能。- 提供额外的元数据用于生成文档、配置文件等。- 在运行时通过反射获取注解信息实现一些特定的逻辑。- 与其他框架或工具进行集成实现特定的功能。 总结元注解用于对其他注解进行说明和定义基本注解是Java内置的用于标记和修饰代码的注解而自定义注解是根据业务需求自行定义的注解用于标记和修饰代码并提供额外的元数据和功能。 ( 3 ) 作用 在Spring MVC中自定义注解可以用于实现以下功能 1. 请求映射可以使用自定义注解来标记Controller中的方法用于指定请求的URL路径和请求方法。例如可以定义一个自定义注解GetMapping用于标记处理GET请求的方法简化了在RequestMapping中指定请求方法的操作。2. 参数绑定可以使用自定义注解来标记Controller中方法的参数用于指定参数的来源和绑定规则。例如可以定义一个自定义注解PathVariable用于标记方法参数表示该参数从URL路径中获取。3. 参数校验可以使用自定义注解来标记方法的参数用于指定参数的校验规则。例如可以定义一个自定义注解Valid用于标记方法参数表示该参数需要进行校验。4. AOP切面可以使用自定义注解来标记需要进行AOP切面处理的方法或类。例如可以定义一个自定义注解Log用于标记需要记录日志的方法然后通过AOP切面对标记了Log注解的方法进行日志记录。5. 权限控制可以使用自定义注解来标记需要进行权限控制的方法或类。例如可以定义一个自定义注解RequiresPermission用于标记需要进行权限验证的方法然后通过AOP切面对标记了RequiresPermission注解的方法进行权限验证。 通过自定义注解可以使代码更加简洁、易读并且可以实现一些特定的功能提高开发效率和代码的可维护性。在Spring MVC中自定义注解的应用非常广泛可以根据具体的业务需求进行自定义注解的定义和使用。 二、自定义注解
( 1 ) 如何自定义注解 要自定义注解需要使用Java提供的元注解来对注解进行配置然后使用interface关键字定义注解的名称和属性。以下是自定义注解的步骤 1 . 使用元注解配置注解的行为和作用范围。常用的元注解有 Retention用于指定注解的生命周期。常用的取值有RetentionPolicy.SOURCE注解在编译期丢弃、RetentionPolicy.CLASS注解在编译期保留但在运行时丢弃默认值、RetentionPolicy.RUNTIME注解在运行时保留。Target用于指定注解的作用目标。常用的取值有ElementType.TYPE类、接口、枚举、ElementType.FIELD字段、ElementType.METHOD方法、ElementType.PARAMETER方法参数、ElementType.CONSTRUCTOR构造函数、ElementType.LOCAL_VARIABLE局部变量、ElementType.ANNOTATION_TYPE注解、ElementType.PACKAGE包等。Documented用于指定注解是否包含在JavaDoc中。Inherited用于指定注解是否可以被继承。 Deprecated用于标记已过时的注解。当一个注解被标记为Deprecated时表示该注解已不推荐使用可以使用其他替代的注解。 Native用于指定注解是否为本地注解。本地注解是指由JDK或第三方库提供的注解而不是自定义的注解。 SuppressWarnings用于抑制编译器警告。可以使用SuppressWarnings注解来忽略特定的警告信息例如未使用的变量、未检查的类型转换等。 2 . 使用interface关键字定义注解的名称和属性。注解的名称可以是任意合法的Java标识符通常以大写字母开头。注解的属性使用方法类似于接口的方法可以指定默认值。 3 . 在需要使用注解的地方使用注解。可以在类、方法、字段等地方使用自定义注解并根据注解的属性进行配置。 4 . 在运行时通过反射获取注解信息。可以使用Java的反射机制在运行时获取类、方法、字段等上的注解信息并根据注解的属性进行特定的逻辑处理。 以下是一个示例演示了如何自定义一个简单的注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;Retention(RetentionPolicy.RUNTIME)
Target(ElementType.METHOD)
public interface MyAnnotation {String value() default ;int count() default 0;
}在上面的示例中定义了一个名为MyAnnotation的注解使用了Retention(RetentionPolicy.RUNTIME)元注解指定了注解在运行时保留使用了Target(ElementType.METHOD)元注解指定了注解可以应用在方法上。注解中定义了两个属性一个是value一个是count并指定了默认值。 然后可以在需要使用注解的地方使用MyAnnotation来标记方法
并根据需要配置注解的属性值
MyAnnotation(value Hello, count 10)
public void myMethod() {// do something
}在运行时可以使用反射来获取注解的信息
Method method MyClass.class.getMethod(myMethod);
MyAnnotation annotation method.getAnnotation(MyAnnotation.class);
String value annotation.value(); // 获取注解的属性值
int count annotation.count();通过以上步骤就可以自定义注解并在代码中使用了。根据具体的业务需求可以定义不同的注解并使用注解来实现特定的功能。 ( 2 ) 场景演示 创建完项目之后找到 pom.xml 配置文件 进行项目引用导入。 ?xml version1.0 encodingUTF-8?project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactIdCloudJunzySSM/artifactIdversion1.0-SNAPSHOT/versionpackagingwar/packagingnameCloudJunzySSM Maven Webapp/name!-- FIXME change it to the projects website --urlhttp://www.example.com/urlpropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmaven.compiler.source1.8/maven.compiler.sourcemaven.compiler.target1.8/maven.compiler.targetmaven.compiler.plugin.version3.7.0/maven.compiler.plugin.version!--添加jar包依赖--!--1.spring 5.0.2.RELEASE相关--spring.version5.0.2.RELEASE/spring.version!--2.mybatis相关--mybatis.version3.4.5/mybatis.version!--mysql--mysql.version5.1.44/mysql.version!--pagehelper分页jar依赖--pagehelper.version5.1.2/pagehelper.version!--mybatis与spring集成jar依赖--mybatis.spring.version1.3.1/mybatis.spring.version!--3.dbcp2连接池相关 druid--commons.dbcp2.version2.1.1/commons.dbcp2.versioncommons.pool2.version2.4.3/commons.pool2.version!--4.log日志相关--log4j2.version2.9.1/log4j2.versionlog4j2.disruptor.version3.2.0/log4j2.disruptor.versionslf4j.version1.7.13/slf4j.version!--5.其他--junit.version4.12/junit.versionservlet.version4.0.0/servlet.versionlombok.version1.18.2/lombok.versionmybatis.ehcache.version1.1.0/mybatis.ehcache.versionehcache.version2.10.0/ehcache.versionredis.version2.9.0/redis.versionredis.spring.version1.7.1.RELEASE/redis.spring.versionjackson.version2.9.3/jackson.versionjstl.version1.2/jstl.versionstandard.version1.1.2/standard.versiontomcat-jsp-api.version8.0.47/tomcat-jsp-api.versioncommons-fileupload.version1.3.3/commons-fileupload.versionhibernate-validator.version5.0.2.Final/hibernate-validator.versionshiro.version1.3.2/shiro.version/propertiesdependencies!--1.spring相关--dependencygroupIdorg.springframework/groupIdartifactIdspring-core/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-beans/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-orm/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-tx/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-web/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion${spring.version}/version/dependency!--2.mybatis相关--dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion${mybatis.version}/version/dependency!--mysql--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion${mysql.version}/version/dependency!--pagehelper分页插件jar包依赖--dependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper/artifactIdversion${pagehelper.version}/version/dependency!--mybatis与spring集成jar包依赖--dependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion${mybatis.spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-context-support/artifactIdversion${spring.version}/version/dependency!--mybatis与ehcache整合--dependencygroupIdorg.mybatis.caches/groupIdartifactIdmybatis-ehcache/artifactIdversion${mybatis.ehcache.version}/version/dependency!--ehcache依赖--dependencygroupIdnet.sf.ehcache/groupIdartifactIdehcache/artifactIdversion${ehcache.version}/version/dependencydependencygroupIdredis.clients/groupIdartifactIdjedis/artifactIdversion${redis.version}/version/dependencydependencygroupIdorg.springframework.data/groupIdartifactIdspring-data-redis/artifactIdversion${redis.spring.version}/version/dependencydependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion${jackson.version}/version/dependencydependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-core/artifactIdversion${jackson.version}/version/dependencydependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-annotations/artifactIdversion${jackson.version}/version/dependency!--3.dbcp2连接池相关--dependencygroupIdorg.apache.commons/groupIdartifactIdcommons-dbcp2/artifactIdversion${commons.dbcp2.version}/versionexclusionsexclusionartifactIdcommons-pool2/artifactIdgroupIdorg.apache.commons/groupId/exclusion/exclusions/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-pool2/artifactIdversion${commons.pool2.version}/version/dependency!--springmvc依赖--dependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion${spring.version}/version/dependency!--4.log日志相关依赖--!-- log4j2日志相关依赖 --!-- log配置Log4j2 Slf4j --!-- slf4j核心包--dependencygroupIdorg.slf4j/groupIdartifactIdslf4j-api/artifactIdversion${slf4j.version}/version/dependencydependencygroupIdorg.slf4j/groupIdartifactIdjcl-over-slf4j/artifactIdversion${slf4j.version}/versionscoperuntime/scope/dependency!--核心log4j2jar包--dependencygroupIdorg.apache.logging.log4j/groupIdartifactIdlog4j-api/artifactIdversion${log4j2.version}/version/dependencydependencygroupIdorg.apache.logging.log4j/groupIdartifactIdlog4j-core/artifactIdversion${log4j2.version}/version/dependency!--用于与slf4j保持桥接--dependencygroupIdorg.apache.logging.log4j/groupIdartifactIdlog4j-slf4j-impl/artifactIdversion${log4j2.version}/version/dependency!--web工程需要包含log4j-web非web工程不需要--dependencygroupIdorg.apache.logging.log4j/groupIdartifactIdlog4j-web/artifactIdversion${log4j2.version}/versionscoperuntime/scope/dependency!--需要使用log4j2的AsyncLogger需要包含disruptor--dependencygroupIdcom.lmax/groupIdartifactIddisruptor/artifactIdversion${log4j2.disruptor.version}/version/dependency!--5.其他--dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion${junit.version}/version
!-- scopetest/scope--/dependencydependencygroupIdjavax.servlet/groupIdartifactIdjavax.servlet-api/artifactIdversion${servlet.version}/versionscopeprovided/scope/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion${lombok.version}/versionscopeprovided/scope/dependencydependencygroupIdjstl/groupIdartifactIdjstl/artifactIdversion${jstl.version}/version/dependencydependencygroupIdtaglibs/groupIdartifactIdstandard/artifactIdversion${standard.version}/version/dependencydependencygroupIdorg.apache.tomcat/groupIdartifactIdtomcat-jsp-api/artifactIdversion${tomcat-jsp-api.version}/version/dependencydependencygroupIdcommons-fileupload/groupIdartifactIdcommons-fileupload/artifactIdversion${commons-fileupload.version}/version/dependencydependencygroupIdorg.hibernate/groupIdartifactIdhibernate-validator/artifactIdversion${hibernate-validator.version}/version/dependency!--shiro依赖--dependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-core/artifactIdversion${shiro.version}/version/dependencydependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-web/artifactIdversion${shiro.version}/version/dependencydependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-spring/artifactIdversion${shiro.version}/version/dependency/dependenciesbuildfinalNameCloudJunzySSM/finalNameresources!--解决mybatis-generator-maven-plugin运行时没有将XxxMapper.xml文件放入target文件夹的问题--resourcedirectorysrc/main/java/directoryincludesinclude**/*.xml/include/includes/resource!--解决mybatis-generator-maven-plugin运行时没有将jdbc.properites文件放入target文件夹的问题--resourcedirectorysrc/main/resources/directoryincludesinclude*.properties/includeinclude*.xml/include/includes/resource/resourcespluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion${maven.compiler.plugin.version}/versionconfigurationsource${maven.compiler.source}/sourcetarget${maven.compiler.target}/targetencoding${project.build.sourceEncoding}/encoding/configuration/pluginplugingroupIdorg.mybatis.generator/groupIdartifactIdmybatis-generator-maven-plugin/artifactIdversion1.3.2/versiondependencies!--使用Mybatis-generator插件不能使用太高版本的mysql驱动 --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion${mysql.version}/version/dependency/dependenciesconfigurationoverwritetrue/overwrite/configuration/pluginpluginartifactIdmaven-clean-plugin/artifactIdversion3.1.0/version/plugin!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --pluginartifactIdmaven-resources-plugin/artifactIdversion3.0.2/version/pluginpluginartifactIdmaven-compiler-plugin/artifactIdversion3.8.0/version/pluginpluginartifactIdmaven-surefire-plugin/artifactIdversion2.22.1/version/pluginpluginartifactIdmaven-war-plugin/artifactIdversion3.2.2/version/pluginpluginartifactIdmaven-install-plugin/artifactIdversion2.5.2/version/pluginpluginartifactIdmaven-deploy-plugin/artifactIdversion2.8.2/version/plugin/plugins/build
/project创建配置文件 spring-context.xml ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!-- spring框架和mybatis进行整合的配置文件加载到spring的上下文中--
import resourceclasspath:spring-mybatis.xml/import/beans 创建配置文件 spring-mybatis.xml ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/context xmlns:txhttp://www.springframework.org/schema/txxmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd!--1. 注解式开发 --!-- 注解驱动 --context:annotation-config/!-- 用注解方式注入bean并指定查找范围com.CloudJun及子子孙孙包--context:component-scan base-packagecom.CloudJun/context:property-placeholder locationclasspath:jdbc.properties/bean iddataSource classorg.apache.commons.dbcp2.BasicDataSourcedestroy-methodcloseproperty namedriverClassName value${jdbc.driver}/property nameurl value${jdbc.url}/property nameusername value${jdbc.username}/property namepassword value${jdbc.password}/!--初始连接数--property nameinitialSize value10/!--最大活动连接数--property namemaxTotal value100/!--最大空闲连接数--property namemaxIdle value50/!--最小空闲连接数--property nameminIdle value10/!--设置为-1时如果没有可用连接连接池会一直无限期等待直到获取到连接为止。--!--如果设置为N毫秒则连接池会等待N毫秒等待不到则抛出异常--property namemaxWaitMillis value-1//bean!--4. spring和MyBatis整合 --!--1) 创建sqlSessionFactory--bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean!-- 指定数据源 --property namedataSource refdataSource/!-- 自动扫描XxxMapping.xml文件**是任意路径 --property namemapperLocations valueclasspath*:com/CloudJun/**/mapper/*.xml/!-- 指定别名 --property nametypeAliasesPackage valuecom/CloudJun/**/model/!--配置pagehelper插件--property namepluginsarraybean classcom.github.pagehelper.PageInterceptorproperty namepropertiesvaluehelperDialectmysql/value/property/bean/array/property/bean!--2) 自动扫描com/CloudJun/**/mapper下的所有XxxMapper接口(其实就是DAO接口)并实现这些接口--!-- 即可直接在程序中使用dao接口不用再获取sqlsession对象--bean classorg.mybatis.spring.mapper.MapperScannerConfigurer!--basePackage 属性是映射器接口文件的包路径。--!--你可以使用分号或逗号 作为分隔符设置多于一个的包路径--property namebasePackage valuecom/CloudJun/**/mapper/property namesqlSessionFactoryBeanName valuesqlSessionFactory//beanbean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManagerproperty namedataSource refdataSource //beantx:annotation-driven transaction-managertransactionManager /aop:aspectj-autoproxy/
/beans创建配置文件 spring-mvc.xml ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvc xmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.3.xsd!--1) 扫描com.CloudJun及子子孙孙包下的控制器(扫描范围过大耗时)--context:component-scan base-packagecom.CloudJun/!--2) 此标签默认注册DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter --mvc:annotation-driven /!--3) 创建ViewResolver视图解析器 --bean classorg.springframework.web.servlet.view.InternalResourceViewResolver!-- viewClass需要在pom中引入两个包standard.jar and jstl.jar --property nameviewClassvalueorg.springframework.web.servlet.view.JstlView/propertyproperty nameprefix value/WEB-INF/jsp//property namesuffix value.jsp//bean!--4) 单独处理图片、样式、js等资源 --!-- mvc:resources location/css/ mapping/css/**/mvc:resources location/js/ mapping/js/**/mvc:resources locationWEB-INF/images/ mapping/images/**/--!-- 处理static包里的所有静态资源 --mvc:resources location/static/ mapping/static/**/!-- 处理文件上传下载的资源 --bean idmultipartResolver classorg.springframework.web.multipart.commons.CommonsMultipartResolver!-- 必须和用户JSP 的pageEncoding属性一致以便正确解析表单的内容 --property namedefaultEncoding valueUTF-8/property!-- 文件最大大小(字节) 1024*1024*5050M--property namemaxUploadSize value52428800/property!--resolveLazily属性启用是为了推迟文件解析以便捕获文件大小异常--property nameresolveLazily valuetrue//bean!--lt;!ndash; lt;!ndash;配置自定义拦截器ndash;gt;ndash;gt;--
!-- mvc:interceptors--
!-- bean classcom.CloudJun.Interceptor.OneInterceptor/bean--
!-- /mvc:interceptors--!-- lt;!ndash;2) 配置自定义多拦截器拦截器链ndash;gt;--
!-- mvc:interceptors--
!-- lt;!ndash; 拦截所以有用请求地址 ndash;gt;--
!-- mvc:interceptor--
!-- mvc:mapping path/**/--
!-- bean classcom.CloudJun.Interceptor.OneInterceptor/--
!-- /mvc:interceptor--
!-- lt;!ndash; 只拦截中间有用名为clz的请求地址 ndash;gt;--
!-- mvc:interceptor--
!-- mvc:mapping path/hot/**/--
!-- bean classcom.CloudJun.Interceptor.TwoInterceptor/--
!-- /mvc:interceptor--
!-- /mvc:interceptors--!--lt;!ndash; 用户权限的请求拦截ndash;gt;--
!-- mvc:interceptors--
!-- bean classcom.CloudJun.Interceptor.LoginInterceptor/bean--
!-- /mvc:interceptors--bean classorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapterproperty namemessageConverterslistref beanmappingJackson2HttpMessageConverter//list/property/beanbean idmappingJackson2HttpMessageConverterclassorg.springframework.http.converter.json.MappingJackson2HttpMessageConverter!--处理中文乱码以及避免IE执行AJAX时返回JSON出现下载文件--property namesupportedMediaTypeslistvaluetext/html;charsetUTF-8/valuevaluetext/json;charsetUTF-8/valuevalueapplication/json;charsetUTF-8/value/list/property/bean!-- springmvc提供的简单异常处理器 --bean classorg.springframework.web.servlet.handler.SimpleMappingExceptionResolver!-- 定义默认的异常处理页面 --property namedefaultErrorView valueerror/!-- 定义异常处理页面用来获取异常信息的变量名也可不定义默认名为exception --property nameexceptionAttribute valueex/!-- 定义需要特殊处理的异常这是重要点 --property nameexceptionMappingspropsprop keyjava.lang.RuntimeExceptionerror/prop/props!-- 还可以定义其他的自定义异常 --/property/bean!--处理controller层发送请求到biz层会经过切面拦截处理--aop:aspectj-autoproxy/
/beans 也可以不进行以上配置及导入一下是基于我博客中代码进行知识点扩展 SpringMVC之JSON数据返回及异常处理机制 重写创建的项目才需要导入以上引用及配置 场景一获取类与方法上的注解值 创建 TranscationModel 直接C到包里接口 package com.CloudJun.annotation;public enum TranscationModel {Read, Write, ReadWrite
} 创建 MyAnnotation1 直接C到包里接口 package com.CloudJun.annotation;import java.lang.annotation.*;/*** author CloudJun* MyAnnotation1注解可以用在类、接口、属性、方法上* 注解运行期也保留* 不可继承*/
Target({ElementType.TYPE, ElementType.FIELD,ElementType.METHOD})
Retention(RetentionPolicy.RUNTIME)
//Inherited //继承使用需要该注解否则读取不到已继承的注解及属性
Documented
public interface MyAnnotation1 {String name();
} 创建 MyAnnotation2 直接C到包里接口 package com.CloudJun.annotation;import java.lang.annotation.*;/*** author CloudJun* MyAnnotation2注解可以用在方法上* 注解运行期也保留* 不可继承*/
Target(ElementType.METHOD)
Retention(RetentionPolicy.RUNTIME)
Documented
public interface MyAnnotation2 {TranscationModel model() default TranscationModel.ReadWrite;
}创建 MyAnnotation3 直接C到包里接口 package com.CloudJun.annotation;import java.lang.annotation.*;/*** author CloudJun* MyAnnotation3注解可以用在方法上* 注解运行期也保留* 可继承*/
Target(ElementType.METHOD)
Retention(RetentionPolicy.RUNTIME)
Inherited
Documented
public interface MyAnnotation3 {TranscationModel[] models() default TranscationModel.ReadWrite;
}创建测试类进行自定义注解测试 Demo1 package com.CloudJun.annotation.Demo1;import com.CloudJun.annotation.MyAnnotation1;
import com.CloudJun.annotation.MyAnnotation2;
import com.CloudJun.annotation.MyAnnotation3;
import com.CloudJun.annotation.TranscationModel;/*** author CloudJun* 获取类与方法上的注解值*/
MyAnnotation1(name Cloud)
public class Demo1 {MyAnnotation1(name Jun)private Integer age;MyAnnotation2(model TranscationModel.Read)public void list() {System.out.println(list);}MyAnnotation3(models {TranscationModel.Read, TranscationModel.Write})public void edit() {System.out.println(edit);}
}创建测试类进行自定义注解测试 Demo1Test package com.CloudJun.annotation.Demo1;import com.CloudJun.annotation.MyAnnotation1;
import com.CloudJun.annotation.MyAnnotation2;
import com.CloudJun.annotation.MyAnnotation3;
import com.CloudJun.annotation.TranscationModel;
import org.junit.Test;/*** author CloudJun*/
public class Demo1Test {Testpublic void list() throws Exception {
// 获取类上的注解MyAnnotation1 annotation1 Demo2.class.getAnnotation(MyAnnotation1.class);System.out.println(annotation1.name());//Cloud// 获取方法上的注解MyAnnotation2 myAnnotation2 Demo1.class.getMethod(list).getAnnotation(MyAnnotation2.class);System.out.println(myAnnotation2.model());//Read// 获取属性上的注解MyAnnotation1 myAnnotation1 Demo1.class.getDeclaredField(age).getAnnotation(MyAnnotation1.class);System.out.println(myAnnotation1.name());// Jun}Testpublic void edit() throws Exception {MyAnnotation3 myAnnotation3 Demo1.class.getMethod(edit).getAnnotation(MyAnnotation3.class);for (TranscationModel model : myAnnotation3.models()) {System.out.println(model);//Read,Write}}
}执行其中的方法 list 进行测试输出结果如下 : 执行其中的方法 edit进行测试输出结果如下 : 场景二 获取类属性上的注解属性值 场景自定义注解 TestAnnotation package com.CloudJun.annotation.Demo2;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** author CloudJun*/
//Retention(RetentionPolicy.SOURCE)
Retention(RetentionPolicy.RUNTIME)
Target(ElementType.FIELD)
public interface TestAnnotation {String value() default 默认value值;String what() default 这里是默认的what属性对应的值;
}创建测试类进行自定义注解的测试 Demo2 package com.CloudJun.annotation.Demo2;/*** author CloudJun* 获取类属性上的注解属性值*/
public class Demo2 {TestAnnotation(value 这里是value对应的值--msg1, what 这里是what对应的值--msg1)private static String msg1;TestAnnotation(这就是value对应的值pa)private static String msg2;TestAnnotation(value 这就是value对应的值as)private static String msg3;TestAnnotation(what 这就是what对应的值)private static String msg4;
}创建测试类进行自定义注解的测试 Demo2Test package com.CloudJun.annotation.Demo2;import org.junit.Test;/*** author CloudJun* 1.value--默认值* 2.default--默认值的赋予*/
public class Demo2Test {Testpublic void test1() throws Exception {TestAnnotation msg1 Demo2.class.getDeclaredField(msg1).getAnnotation(TestAnnotation.class);System.out.println(msg1.value());System.out.println(msg1.what());}Testpublic void test2() throws Exception{TestAnnotation msg2 Demo2.class.getDeclaredField(msg2).getAnnotation(TestAnnotation.class);System.out.println(msg2.value());System.out.println(msg2.what());}Testpublic void test3() throws Exception{TestAnnotation msg3 Demo2.class.getDeclaredField(msg3).getAnnotation(TestAnnotation.class);System.out.println(msg3.value());System.out.println(msg3.what());}Testpublic void test4() throws Exception{TestAnnotation msg4 Demo2.class.getDeclaredField(msg4).getAnnotation(TestAnnotation.class);System.out.println(msg4.value());System.out.println(msg4.what());}
}执行其中 test1 的方法进行测试输出结果为 : 执行其中 test2 的方法进行测试输出结果为 : 执行其中 test3 的方法进行测试输出结果为 : 执行其中 test4 的方法进行测试输出结果为 : 场景三 获取参数修饰注解对应的属性值 创建自定义注解 IsNotNull package com.CloudJun.annotation.Demo3;import java.lang.annotation.*;/*** author CloudJun* 非空注解* 使用在方法的参数上false表示此参数可以为空true不能为空*/
Documented
Target({ElementType.PARAMETER})
Retention(RetentionPolicy.RUNTIME)
public interface IsNotNull {boolean value() default false;
}创建测试类 Demo3 package com.CloudJun.annotation.Demo3;/*** author CloudJun* 获取参数修饰注解对应的属性值*/
public class Demo3 {public void hello1(IsNotNull(true) String name) {System.out.println(hello: name);}public void hello2(IsNotNull String name) {System.out.println(hello: name);}
}创建测试类 Demo3Test进行方法测试 package com.CloudJun.annotation.Demo3;import org.junit.Test;import java.lang.reflect.Method;
import java.lang.reflect.Parameter;/*** author CloudJun*/
public class Demo3Test {Testpublic void hello1() throws Exception {Demo3 demo3 new Demo3();for (Parameter parameter : demo3.getClass().getMethod(hello1, String.class).getParameters()) {IsNotNull annotation parameter.getAnnotation(IsNotNull.class);if(annotation ! null){//如果值没有设置将会是默认值为:falseSystem.out.println(annotation.value());//true}}}Testpublic void hello2() throws Exception {Demo3 demo3 new Demo3();for (Parameter parameter : demo3.getClass().getMethod(hello2, String.class).getParameters()) {IsNotNull annotation parameter.getAnnotation(IsNotNull.class);if(annotation ! null){//如果值有设置将会是默认值为:trueSystem.out.println(annotation.value());//false}}}Testpublic void hello3() throws Exception {
// 模拟浏览器传递到后台的参数 解读requestParamString name 独孤九剑;Demo3 demo3 new Demo3();Method method demo3.getClass().getMethod(hello1, String.class);for (Parameter parameter : method.getParameters()) {IsNotNull annotation parameter.getAnnotation(IsNotNull.class);if(annotation ! null){System.out.println(annotation.value());//trueif (annotation.value() !.equals(name)){method.invoke(demo3,name);}}}}
}执行其中的方法( hello1 )进行测试输出结果为 : 执行其中的方法( hello2 )进行测试输出结果为 : 执行其中的方法( hello3 )进行测试输出结果为 : 三、Aop自定义注解的应用 AOP面向切面编程是一种编程范式它通过在程序运行时动态地将额外的逻辑织入到方法或类中从而实现对方法或类的增强。自定义注解可以与AOP结合使用用于标记需要进行增强的方法或类。 以下是一个示例演示了如何使用自定义注解与AOP结合实现日志记录的功能 1 .定义自定义注解MyLog用于标记需要记录日志的方法
package com.CloudJun.annotation.aop;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/*** author CloudJun*/
Target(ElementType.METHOD)
Retention(RetentionPolicy.RUNTIME)
public interface MyLog {String desc();
}2 . 定义切面类MyLogAspect在该类中定义增强逻辑例如记录日志
package com.CloudJun.aspect;import com.CloudJun.annotation.aop.MyLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;/*** author CloudJun*/
Component
Aspect
public class MyLogAspect {private static final Logger logger LoggerFactory.getLogger(MyLogAspect.class);/*** 只要用到了com.CloudJun.annotation.aop.MyLog这个注解的就是目标类* 是目标类就会执行以下before方法里的代码*/Pointcut(annotation(com.CloudJun.annotation.aop.MyLog))private void MyValid() {}Before(MyValid())public void before(JoinPoint joinPoint) {MethodSignature signature (MethodSignature) joinPoint.getSignature();logger.debug([ signature.getName() : start.....]);System.out.println([ signature.getName() : start.....]);MyLog myLog signature.getMethod().getAnnotation(MyLog.class);logger.debug(【目标对象方法被调用时候产生的日志记录到日志表中】myLog.desc());System.out.println(【目标对象方法被调用时候产生的日志记录到日志表中】 myLog.desc());}// Around(MyValid())
// public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
// long startTime System.currentTimeMillis();
// System.out.println(pjp.getTarget());//获取目标方法
// System.out.println(pjp.getThis());//
// Object[] args pjp.getArgs();//获取参数
// System.out.println(Arrays.toString(args));//输出参数
// Object ob pjp.proceed();//获取方法返回值
// System.out.println(ob);//输出返回值
// logger.info(耗时 : (System.currentTimeMillis() - startTime));
// return ob;
// }}在上面的切面类中使用Aspect注解标记该类为切面类。Pointcut(annotation(com.CloudJun.annotation.aop.MyLog))注解用于定义切点表示匹配所有标记有Log注解的方法。Before注解表示在目标方法执行前执行增强逻辑。 3 . 创建一个控制器 LogController package com.CloudJun.web;import com.CloudJun.annotation.aop.MyLog;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;/*** author CloudJun*/
Controller
public class LogController {RequestMapping(/myLog)MyLog(desc 这是结合spring aop知识讲解自定义注解应用的一个案例)public void testLogAspect(HttpServletRequest request){request.getRemoteAddr();//这里是获取请求IP,可以输出或者保存在某个地方及属性request.getRemotePort();//这里是获取请求端口,可以输出或者保存在某个地方及属性System.out.println(这里随便来点啥);}
}自定义注解与AOP结合使用可以实现各种不同的功能如权限控制、性能监控、事务管理等。根据具体的业务需求可以定义不同的注解并在切面类中实现相应的增强逻辑。 测试 开启服务器在浏览器中进行访问地址进行测试( 以下访问地址是根据自己配置而修改的 ) 访问该地址进行测试 : localhost:8081/ssm/ myLog ( 结果如下 ) 将切面类中( MyLogAspect ) 的 before 方法进行注释将其中的 doAround 方法注释打开 同样访问该地址进行测试 : localhost:8081/ssm/myLog ( 结果如下 ) 小总结 通过自定义注解与AOP结合使用可以实现各种不同的功能根据具体的业务需求进行定制化开发。这种方式可以将横切逻辑与业务逻辑分离提高代码的可维护性和可扩展性同时也减少了代码的重复编写。 带给我们的收获 学习SpringMVC中的自定义注解和AOP自定义注解的应用可以带来以下几个方面的收获 1. 提高代码重用性通过自定义注解我们可以将一些常用的功能逻辑抽象为注解然后在需要的地方进行标记和使用。这样可以减少代码的重复编写提高代码的可维护性和可读性。 2. 简化开发流程通过自定义注解我们可以简化一些繁琐的配置和操作。比如在SpringMVC中我们可以使用自定义注解来标记控制器的映射路径从而省去手动配置URL映射的步骤简化了开发流程。 3. 实现横切关注点AOP面向切面编程可以通过自定义注解来实现横切关注点的功能例如日志记录、事务管理、权限控制等。通过在代码中标记自定义注解可以将这些关注点与业务逻辑分离提高代码的可维护性和可扩展性。 4. 代码解耦和模块化通过自定义注解和AOP我们可以将一些功能逻辑和横切关注点从业务代码中解耦出来实现模块化的开发。这样可以降低代码的耦合度提高代码的可测试性和可维护性。 总的来说学习SpringMVC中的自定义注解和AOP自定义注解的应用可以提高代码的重用性、简化开发流程实现横切关注点解耦业务代码从而带来更加高效、可维护和可扩展的代码开发和管理。