当前位置: 首页 > wzjs >正文

深圳优质网站建设案例网站百度推广怎么做

深圳优质网站建设案例,网站百度推广怎么做,临沂市建设局网站改版,wordpress空间转服务器1、AOP面向切面编程 1. Target(ElementType.METHOD) 作用:指定自定义注解可以应用的目标范围。 参数:ElementType 是一个枚举类,定义了注解可以应用的目标类型。 ElementType.METHOD 表示该注解只能用于方法上。 其他常见的 ElementType 值…

1、AOP面向切面编程

1. @Target(ElementType.METHOD)

  • 作用:指定自定义注解可以应用的目标范围。

  • 参数ElementType 是一个枚举类,定义了注解可以应用的目标类型。

    • ElementType.METHOD 表示该注解只能用于方法上。

    • 其他常见的 ElementType 值:

      • TYPE:类、接口、枚举等。

      • FIELD:字段(包括枚举常量)。

      • PARAMETER:方法参数。

      • CONSTRUCTOR:构造函数。

      • ANNOTATION_TYPE:注解类型。

      • PACKAGE:包。

      • 等等。

示例

@Target(ElementType.METHOD)
public @interface MyAnnotation {String value() default "";
}
  • 上面的 @MyAnnotation 注解只能用于方法上,如果尝试将其用于类或字段上,编译器会报错。


2. @Retention(RetentionPolicy.RUNTIME)

  • 作用:指定自定义注解的生命周期,即注解在什么阶段有效。

  • 参数RetentionPolicy 是一个枚举类,定义了注解的保留策略。

    • RetentionPolicy.RUNTIME:注解在运行时保留,可以通过反射机制读取。

    • RetentionPolicy.CLASS:注解在编译时保留,但运行时不可见(默认行为)。

    • RetentionPolicy.SOURCE:注解仅在源码阶段保留,编译后会被丢弃。

示例

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {String value() default "";
}
  • 上面的 @MyAnnotation 注解在运行时仍然有效,可以通过反射获取注解信息。


结合使用

通常,@Target 和 @Retention 会一起使用,以明确注解的作用范围和生命周期。

示例

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD) // 该注解只能用于方法上
@Retention(RetentionPolicy.RUNTIME) // 该注解在运行时有效
public @interface MyAnnotation {String value() default "";
}

使用场景

public class MyClass {@MyAnnotation(value = "This is a method")public void myMethod() {System.out.println("Hello, World!");}
}

通过反射获取注解信息

import java.lang.reflect.Method;public class Main {public static void main(String[] args) throws Exception {Method method = MyClass.class.getMethod("myMethod");MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);if (annotation != null) {System.out.println("Annotation value: " + annotation.value());}}
}

输出

Annotation value: This is a method

总结

  • @Target(ElementType.METHOD):指定注解只能用于方法上。

  • @Retention(RetentionPolicy.RUNTIME):指定注解在运行时仍然有效,可以通过反射读取。

  • 这两个注解通常一起使用,用于定义自定义注解的行为和适用范围。

3、反射(Reflection)

 是 Java 提供的一种强大的机制,允许程序在运行时动态地获取类的信息(如类名、方法、字段、构造函数等),并操作这些信息(如调用方法、访问字段、创建对象等)。反射的核心思想是“在运行时检查和修改程序的行为”。

反射的主要用途包括:

  1. 动态加载类。

  2. 动态创建对象。

  3. 动态调用方法。

  4. 动态访问和修改字段。

  5. 获取注解信息。


反射的核心类

Java 反射的核心类和接口位于 java.lang.reflect 包中,主要包括:

  • Class<T>:表示一个类或接口,是反射的入口。

  • Method:表示类的方法。

  • Field:表示类的字段(成员变量)。

  • Constructor<T>:表示类的构造函数。

  • Annotation:表示注解。


反射的基本用法

1. 获取 Class 对象

Class 对象是反射的起点,可以通过以下方式获取:

  • Class.forName("全限定类名"):通过类的全限定名获取。

  • 对象.getClass():通过对象的实例获取。

  • 类名.class:通过类字面量获取。

示例

Class<?> clazz = Class.forName("com.example.MyClass");
2. 创建对象

通过 Class 对象可以动态创建类的实例。

示例

Class<?> clazz = Class.forName("com.example.MyClass");
Object obj = clazz.getDeclaredConstructor().newInstance();
3. 调用方法

通过 Method 对象可以动态调用类的方法。

示例

Class<?> clazz = Class.forName("com.example.MyClass");
Object obj = clazz.getDeclaredConstructor().newInstance();// 获取方法
Method method = clazz.getMethod("myMethod", String.class);// 调用方法
method.invoke(obj, "Hello, Reflection!");
4. 访问字段

通过 Field 对象可以动态访问和修改类的字段。

示例

Class<?> clazz = Class.forName("com.example.MyClass");
Object obj = clazz.getDeclaredConstructor().newInstance();// 获取字段
Field field = clazz.getDeclaredField("myField");// 设置字段可访问(如果是私有字段)
field.setAccessible(true);// 修改字段值
field.set(obj, "New Value");// 获取字段值
Object value = field.get(obj);
System.out.println(value);
5. 获取注解信息

通过反射可以获取类、方法、字段等元素上的注解信息。

示例

Class<?> clazz = Class.forName("com.example.MyClass");// 获取类上的注解
MyAnnotation classAnnotation = clazz.getAnnotation(MyAnnotation.class);
if (classAnnotation != null) {System.out.println("Class Annotation Value: " + classAnnotation.value());
}// 获取方法上的注解
Method method = clazz.getMethod("myMethod");
MyAnnotation methodAnnotation = method.getAnnotation(MyAnnotation.class);
if (methodAnnotation != null) {System.out.println("Method Annotation Value: " + methodAnnotation.value());
}

反射的优缺点

优点
  1. 灵活性:可以在运行时动态加载类、调用方法、访问字段,适合编写通用框架或工具。

  2. 扩展性:通过反射可以实现插件化架构,动态加载第三方类。

  3. 注解处理:反射是处理注解的基础,许多框架(如 Spring、MyBatis)都依赖反射来解析注解。

缺点
  1. 性能开销:反射操作比直接调用方法或访问字段要慢,因为涉及动态解析。

  2. 安全性问题:反射可以绕过访问控制(如访问私有字段或方法),可能导致安全问题。

  3. 代码可读性差:反射代码通常比较复杂,难以理解和维护。


反射的实际应用场景

  1. 框架开发:许多框架(如 Spring、Hibernate、MyBatis)都使用反射来实现依赖注入、动态代理、注解解析等功能。

  2. 单元测试:测试框架(如 JUnit)使用反射来调用测试方法。

  3. 动态加载类:在插件化架构中,通过反射动态加载第三方类。

  4. 序列化和反序列化:通过反射访问对象的字段,实现对象的序列化和反序列化。


示例代码

以下是一个完整的反射示例,展示了如何通过反射创建对象、调用方法和访问字段:

import java.lang.reflect.Field;
import java.lang.reflect.Method;public class ReflectionExample {public static void main(String[] args) throws Exception {// 获取 Class 对象Class<?> clazz = Class.forName("com.example.MyClass");// 创建对象Object obj = clazz.getDeclaredConstructor().newInstance();// 调用方法Method method = clazz.getMethod("myMethod", String.class);method.invoke(obj, "Hello, Reflection!");// 访问字段Field field = clazz.getDeclaredField("myField");field.setAccessible(true); // 设置私有字段可访问field.set(obj, "New Value");System.out.println("Field Value: " + field.get(obj));}
}class MyClass {private String myField = "Default Value";public void myMethod(String message) {System.out.println("Method Invoked: " + message);}
}

输出

Method Invoked: Hello, Reflection!
Field Value: New Value

总结

反射是 Java 中一种强大的机制,允许程序在运行时动态操作类和对象。虽然反射提供了极大的灵活性,但也带来了性能开销和安全性问题,因此应谨慎使用。在实际开发中,反射常用于框架开发、注解处理、动态加载类等场景。

4、idea快捷键ctrl + alt + b

快速转到接口实现方法。

5、实战

1 步骤一

自定义注解 AutoFill

进入到sky-server模块,创建com.sky.annotation包。

package com.sky.annotation;import com.sky.enumeration.OperationType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 自定义注解,用于标识某个方法需要进行功能字段自动填充处理*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {//数据库操作类型:UPDATE INSERTOperationType value();
}

其中OperationType已在sky-common模块中定义

package com.sky.enumeration;/*** 数据库操作类型*/
public enum OperationType {/*** 更新操作*/UPDATE,/*** 插入操作*/INSERT
}
2 步骤二

自定义切面 AutoFillAspect

在sky-server模块,创建com.sky.aspect包。

package com.sky.aspect;/*** 自定义切面,实现公共字段自动填充处理逻辑*/
@Aspect
@Component
@Slf4j
public class AutoFillAspect {/*** 切入点*/@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")public void autoFillPointCut(){}/*** 前置通知,在通知中进行公共字段的赋值*/@Before("autoFillPointCut()")public void autoFill(JoinPoint joinPoint){/重要//可先进行调试,是否能进入该方法 提前在mapper方法添加AutoFill注解log.info("开始进行公共字段自动填充...");}
}

完善自定义切面 AutoFillAspect 的 autoFill 方法

package com.sky.aspect;import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
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.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.time.LocalDateTime;/*** 自定义切面,实现公共字段自动填充处理逻辑*/
@Aspect
@Component
@Slf4j
public class AutoFillAspect {/*** 切入点*/@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")public void autoFillPointCut(){}/*** 前置通知,在通知中进行公共字段的赋值*/@Before("autoFillPointCut()")public void autoFill(JoinPoint joinPoint){log.info("开始进行公共字段自动填充...");//获取到当前被拦截的方法上的数据库操作类型MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法签名对象AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象OperationType operationType = autoFill.value();//获得数据库操作类型//获取到当前被拦截的方法的参数--实体对象Object[] args = joinPoint.getArgs();if(args == null || args.length == 0){return;}Object entity = args[0];//准备赋值的数据LocalDateTime now = LocalDateTime.now();Long currentId = BaseContext.getCurrentId();//根据当前不同的操作类型,为对应的属性通过反射来赋值if(operationType == OperationType.INSERT){//为4个公共字段赋值try {Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);//通过反射为对象属性赋值setCreateTime.invoke(entity,now);setCreateUser.invoke(entity,currentId);setUpdateTime.invoke(entity,now);setUpdateUser.invoke(entity,currentId);} catch (Exception e) {e.printStackTrace();}}else if(operationType == OperationType.UPDATE){//为2个公共字段赋值try {Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);//通过反射为对象属性赋值setUpdateTime.invoke(entity,now);setUpdateUser.invoke(entity,currentId);} catch (Exception e) {e.printStackTrace();}}}
}
3 步骤三

在Mapper接口的方法上加入 AutoFill 注解

CategoryMapper为例,分别在新增和修改方法添加@AutoFill()注解,也需要EmployeeMapper做相同操作

package com.sky.mapper;@Mapper
public interface CategoryMapper {/*** 插入数据* @param category*/@Insert("insert into category(type, name, sort, status, create_time, update_time, create_user, update_user)" +" VALUES" +" (#{type}, #{name}, #{sort}, #{status}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})")@AutoFill(value = OperationType.INSERT)void insert(Category category);/*** 根据id修改分类* @param category*/@AutoFill(value = OperationType.UPDATE)void update(Category category);}

同时,将业务层为公共字段赋值的代码注释掉。

1). 将员工管理的新增和编辑方法中的公共字段赋值的代码注释。

2). 将菜品分类管理的新增和修改方法中的公共字段赋值的代码注释。


文章转载自:

http://ZmpyxqGn.prddp.cn
http://2PewEDEs.prddp.cn
http://LJOYDD9a.prddp.cn
http://JU8075oW.prddp.cn
http://eaXhAVRz.prddp.cn
http://rgGkxwrP.prddp.cn
http://izyKbinx.prddp.cn
http://z3T7vHhs.prddp.cn
http://JGOE67lI.prddp.cn
http://ZBQMp7Jb.prddp.cn
http://aRtylY01.prddp.cn
http://vYte4fmL.prddp.cn
http://BrO5EhCA.prddp.cn
http://lghGvw64.prddp.cn
http://gqb1ojzO.prddp.cn
http://6YPAugmO.prddp.cn
http://E58NPAuC.prddp.cn
http://Ql1NuUP9.prddp.cn
http://THbpHEA5.prddp.cn
http://AsOEXLbt.prddp.cn
http://uouV8oaM.prddp.cn
http://bwTjFetH.prddp.cn
http://d6qHyZWW.prddp.cn
http://vnlHGKRQ.prddp.cn
http://3VDEHGrC.prddp.cn
http://AHXSV4HT.prddp.cn
http://v0iQ1nuo.prddp.cn
http://G3Ph48S8.prddp.cn
http://ORQKtP4X.prddp.cn
http://LhE00KFx.prddp.cn
http://www.dtcms.com/wzjs/680462.html

相关文章:

  • 深圳企业建站模板做网站合同
  • 做网站创业怎么样乐清虹桥门户网
  • 世界杯网站源码下载做电影网站 资源怎么存放
  • 网站系统与网站源码的关系正规的推文平台
  • 学会了dw就可以做网站吗网站上线 flash
  • 怎么在vk网站上做推广flash相册网站源码
  • 织梦cms仿某作文网站整站源码(带采集)安装数据库wordpress首页调用文章数
  • 网站降权怎么办wordpress 客户端管理
  • 做二手手机交易网站国内外网站网站
  • 做的最好的视频教学网站seo什么意思
  • 做网站需要会什么软件董技叔app开发公司
  • 茂名公司制作网站品牌建设找晓哥
  • 爱爱做网站黄浦专业做网站
  • 网站建设的设计总结西安域名注册
  • WordPress建影视站中山古镇做网站
  • 保定公司做网站平面设计培训课程培训
  • 开网络网站建设公司的优势平面设计师务所
  • 仿制别人网站品牌设计理念
  • 音乐网站开发文档撰写模板长久新开传奇网站
  • 四川餐饮网站建设农村自建房设计图纸及效果图大全
  • 专业网站开发公司地址海南学校网站建设
  • 东阿县住房和城乡建设局网站网络建设方案总结
  • 吉安做网站百度站长统计
  • 如何网站建设网站小程序平台开发多少钱
  • 番禺网站推广公司云南公司网站建设
  • 莆田建设信息网站免费建网站 建站之星
  • 怎么用vps做网站wordpress 自动剪裁
  • pc网站同步手机网站比58同城做的好的网站
  • 网页设计的定义seo sem是做什么的
  • iis6.0如何做网站301免费咨询律师在线一对一问答