转载 反射技术 反射的基本的概念

https://note.youdao.com/ynoteshare/index.html?id=75a5a9c30785e57c55b5a188df271f95&type=note&_time=1641737823295

反射技术

反射的基本的概念
使用反射机制可以动态获取当前class的信息 比如方法的信息、注解信息、方法的参数、属性等;

反射技术应用的场景

  1. JDBC加载驱动连接 class.forname
  2. Spring容器框架IOC实例化对象
  3. 自定义注解生效(反射+Aop)
  4. 第三方核心的框架

反射技术的使用

Class类 代表类的实体,在运行的Java应用程序中表示类和接口
Field类 代表类的成员变量(成员变量也称为类的属性)

Method类 代表类的方法
Constructor类 代表类的构造方法
使用反射机制初始化对象 获取当前class的信息

Class<?> aClass = Class.forName("com.mayikt.entity.UserEntity");

执行无参数构造函数

Class<?> aClass = Class.forName("com.mayikt.entity.UserEntity");
UserEntity userEntity = (UserEntity) aClass.newInstance();
userEntity.setName("mayikt");
userEntity.setUserId(1234);
System.out.println(userEntity);

执行有参数构造函数

Class<?> aClass = Class.forName("com.mayikt.entity.UserEntity");**
// 执行有参数构造函数
Constructor<?> constructor = aClass.
        getConstructor(Integer.class, String.class);
UserEntity userEntity = (UserEntity) constructor.
        newInstance(10, "mayikt");
System.out.println(userEntity);

使用反射机制给属性赋值

 Class<?> aClass = Class.forName("com.mayikt.entity.UserEntity");

// 给私有属性赋值

 UserEntity  userEntity = (UserEntity) aClass.newInstance();
 Field userId = aClass.getDeclaredField("userId");
 userId.setAccessible(true);
 userId.set(userEntity,12);
 Field name = aClass.getDeclaredField("name");
 name.setAccessible(true);
 name.set(userEntity,"mayikt");
 System.out.println(userEntity);


Exception in thread "main" java.lang.IllegalAccessException: Class com.mayikt.Test001 can not access a member of class com.mayikt.entity.UserEntity with modifiers "private"
	at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
	at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)

如果使用反射给私有属性或者调用私有的方法 都需要设置权限
使用反射机制给调用方法

  Class<?> aClass = Class.forName("com.mayikt.entity.UserEntity");

// 给私有属性赋值

 UserEntity  userEntity = (UserEntity) aClass.newInstance();
 Method meite = aClass.getDeclaredMethod("meite", Integer.class);
 meite.setAccessible(true);
 Object invoke = meite.invoke(userEntity, 10);
 System.out.println(invoke);

获取自定义注解
field.getAnnotation();


Class dtoClass = formFillingStatisticsResDto.class;
        List<Field> fieldList = Arrays.stream(dtoClass.getDeclaredFields())
                .filter(t -> t.getAnnotation(QueryResult.class) != null)
                .collect(Collectors.toList());
 formFillingStatisticsResDto checkFormFillingStatisticsResDto = new formFillingStatisticsResDto();
 formFillingStatisticsResDto .setCheckPointName("汇总");
 formFillingStatisticsResDto .setDutyName("/");
        
 private void buildSumCheckformllingStatisticResdtoList(List<formFillingStatisticsResDto> statisticsResDtoList) {
        Class dtoClass = formFillingStatisticsResDto.class;
        List<Field> fieldList = Arrays.stream(dtoClass.getDeclaredFields())
                .filter(t -> t.getAnnotation(QueryResult.class) != null)
                .collect(Collectors.toList());
        formFillingStatisticsResDto formFillingStatisticsResDto = new formFillingStatisticsResDto ();
        formFillingStatisticsResDto.setCheckPointName("汇总");
        checkFormFillingStatisticsResDto.setDutyName("/");
        fieldList.forEach(field -> {
            String filedName = field.getName();
            try {
                long sum = 0;
                for (CheckFormFillingStatisticsResDto checkFormFillingStatistics : statisticsResDtoList) {
          Method getMethod = dtoClass.getMethod("get" + filedName.substring(0, 1).toUpperCase() + filedName.substring(1, filedName.length()));
                    sum = sum + (Long) getMethod.invoke(checkFormFillingStatistics);
                }
     Method dtoSetMethod = dtoClass.getMethod("set" + filedName.substring(0, 1).toUpperCase() + filedName.substring(1, filedName.length()), Long.class);
          dtoSetMethod.invoke(formFillingStatisticsResDto , Long.valueOf(sum));
          
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        });
        statisticsResDtoList.add(checkFormFillingStatisticsResDto);
    }

自定义注解

什么是注解
Java注解是Jdk1.5推出一个重大特性 可以标记在类、方法、属性上面
内置注解:
1.@Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
2.@Deprecated - 标记过时方法。如果使用该方法,会报编译警告。

元注解:
@Retention - 标识这个注解怎 么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
@Documented - 标记这些注解是否包含在用户文档中。
@Target - 标记这个注解应该是哪种 Java 成员。
@Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)

注解如何生效

- 通过Aop技术+反射技术
- 反射类+filed.getAnnotation  获取指定字段进行操作

t.getAnnotation(QueryResult.class)

自定义注解

//----------------------------------------------------------------*/

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 ExtTransactional {
    String name();
}
实体类
package com.mayikt.entity;

import com.mayikt.ExtTransactional;
import lombok.Data;

/**
 * @ClassName UserEntity
 * @Author 蚂蚁课堂余胜军 QQ644064779 www.mayikt.com
 * @Version V1.0
 **/
@Data
public class UserEntity {
    private Integer userId;
    private String name;
    public UserEntity(){
        System.out.println("###我是无参构造函数###");
    }

    public UserEntity(Integer userId, String name) {
        this.userId = userId;
        this.name = name;
    }
    @ExtTransactional(name ="mayikt")
    private String  meite(Integer a){
        System.out.println("meite:"+a);
        return "meite66";
    }
}
反射获取
Class<?> aClass = Class.forName("com.mayikt.entity.UserEntity");
UserEntity userEntity = (UserEntity) aClass.newInstance();
Method meite = aClass.getDeclaredMethod("meite", Integer.class);
meite.setAccessible(true);
ExtTransactional declaredAnnotation = meite.getDeclaredAnnotation(ExtTransactional.class);
System.out.println(declaredAnnotation.name());

Spring中事务的类型

  • 手动事务
  • 声明式事务 基于注解+aop实现
    注解自定义 生效+aop+反射技术生效

原理:
AOP技术:
1.AOP技术 在方法前后 拦截
2.前置通知 后置通知 环绕通知 异常通知
3.AOP技术 环绕通知 在我们目标方法之前开启事务 目标方法执行完毕 提交事务或者回滚

事务的原理

手动事务

自定义事务注解

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;

@Component
public class TransactionalUtils {

    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;

    /**
     * begin
     * @return
     */
    public TransactionStatus begin(){
        // 设置传播行为
        TransactionStatus transaction =
                dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
        return transaction;
    }

    /**
     * 提交
     * @param transaction
     */
    public void commit( TransactionStatus transaction){
        dataSourceTransactionManager.commit(transaction);

    }

    /**
     * 回滚
     * @param transaction
     */
    public void rollback(TransactionStatus transaction){
        dataSourceTransactionManager.rollback(transaction);
    }
}

@GetMapping("/insertUser")
public String insertUser(UserEntity userEntity){
    TransactionStatus begin=null;
    try {
        begin = transactionalUtils.begin();
        int j = 1 / userEntity.getUserId();
        String result = userMapper.insertUser(userEntity) > 0 ? "success" : "fail";
        transactionalUtils.commit(begin);
        return "success";
    }catch (Exception e){
        if(begin!=null){
            transactionalUtils.rollback(begin);
        }
        return "fail";
    }

}

Aop切面类

package com.mayikt.aop;

import com.mayikt.utils.TransactionalUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;

/**
 * 基于aop
 */
@Aspect
@Component
public class ExtTransactionalAop {

    @Autowired
    private TransactionalUtils transactionalUtils;

    @Around(value = "@annotation(com.mayikt.aop.ExtTransactional)")
    public Object around(ProceedingJoinPoint joinPoint) {
        TransactionStatus begin = null;
        try {
            begin = transactionalUtils.begin();
            Object result = joinPoint.proceed();
            transactionalUtils.commit(begin);
            return result;
        } catch (Throwable throwable) {
            if (begin != null)
                transactionalUtils.rollback(begin);
            return "fail";
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值