切面编程+反射实现注解式开发

1.本文实现的是订单查询中属性字段(用户名称为空.)通过注解反射方法给customerName填充值。

package com.example.hello.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
/**
 * 注解类
 */
public @interface NeedSetValueField {
    Class<?> beanClass();
    String param();
    String method();
    String targetField();
}
package com.example.hello.aspect;

import com.example.hello.util.BeanUtil;
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 java.util.Collection;

@Component
@Aspect
public class SetFieldValueAspect {
    @Autowired
    BeanUtil beanUtil;

    /**
     * 切面编程环绕执行
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("@annotation(com.example.hello.annotation.NeedSetValue)")
    public Object doSetValue(ProceedingJoinPoint joinPoint)throws Throwable{
       Object result = joinPoint.proceed();
       // 操作结果集,得值进行设置
        beanUtil.setValueByCol((Collection) result);
       return result;
    }
}
package com.example.hello.controller;

import com.example.hello.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    /**
     * 分页查询order
     * @param customerId
     * @param pageNum
     * @param pageSize
     * @return
     * @throws Exception
     */
    @RequestMapping("query")
    public Object query(String customerId, int pageNum, int pageSize)throws Exception{
        return this.orderService.pageQuery(customerId,pageNum,pageSize);
    }
}
package com.example.hello.controller;

import com.example.hello.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    /**
     * 分页查询order
     * @param customerId
     * @param pageNum
     * @param pageSize
     * @return
     * @throws Exception
     */
    @RequestMapping("query")
    public Object query(String customerId, int pageNum, int pageSize)throws Exception{
        return this.orderService.pageQuery(customerId,pageNum,pageSize);
    }
}
package com.example.hello.dao;

import com.example.hello.model.User;
import com.sun.org.glassfish.gmbal.ParameterNames;
import org.springframework.cache.annotation.Cacheable;

import java.util.List;

@Cacheable
public class UserDao {

    void insert(User u) {

    }
    void update(User u){}

    /**
     * 查询用户列表
     * @param username
     * @return
     */
    List<User> query( String username){
        return null;
    }

    /**
     * 根据id查询用户
     * @param id
     * @return
     */
    User find(String id){
        User user = new User("1","1");
        return user ;
    }
}
package com.example.hello.model;


import com.example.hello.annotation.NeedSetValueField;
import com.example.hello.dao.UserDao;

import java.io.Serializable;

public class Order implements Serializable {
    /**
     * list={id:1,cid:1,cname:null}
     */
    private static final long serialVersion = 100000000L;

    private String id;

    private String customerId;
    /**
     * 通过注解实现给customerName赋值
     */
    @NeedSetValueField(beanClass = UserDao.class,param = "customerId",method = "find",targetField = "name")
    private String customerName; //set值 后置方法---反射 user--find-->method.invoke()--->name---获取到具体值
    // --->set

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getCustomerId() {
        return customerId;
    }

    public void setCustomerId(String customerId) {
        this.customerId = customerId;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }


}
package com.example.hello.model;

public class User {
    private static final long serialVersion = 100000001L;
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    private String id;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private String name;
    public User(String id,String name){
        this.id = id;
        this.name = name;
    }
}
package com.example.hello.service;

import com.example.hello.annotation.NeedSetValue;
import com.example.hello.dao.OrderDao;
import com.example.hello.model.Order;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

    /**
     * 1.获取和设置组件
     * 2.首先,当调用组件时,我怎么知道设置哪些属性值
     * 3,这个要告诉我
     * 4.我怎么知道哪个bean的哪个方法,以及要传入的值
     * 5.这个要告诉我
     */

    @Autowired
    private OrderDao orderDao;
    // 执行本方法进行切面
    // 自定义注解切面
    @NeedSetValue
    public Page<Order> pageQuery(String customerId, int pageNum, int pageSize)throws Exception{
        Page<Order> page = PageHelper.startPage(pageNum,pageSize);
        this.orderDao.query(customerId);

        // 批量查询10条
        // util --- setField(class bean,params,setField) ---可以解决问题
        // 更加优雅的方法,不用改动原有的代码
        // 使用AOP进行增强处理,对结果进行设置,再返回
        // annotion 注解,能让类附上说明信息到运行期


        return page;
    }
}
package com.example.hello.util;

import com.example.hello.annotation.NeedSetValueField;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

@Component
public class BeanUtil implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext var1) throws BeansException{
        this.applicationContext = applicationContext;
    }

    public void setValueByCol(Collection col)throws Exception{
        Class<?> clazz = col.iterator().next().getClass();
        Field[] fields = clazz.getDeclaredFields();
        Map<String,Object> cache = new HashMap<>();
        for (Field field: fields) {
            NeedSetValueField sv = field.getAnnotation(NeedSetValueField.class); //拿到定义在属性上的注解
            if (sv == null)continue;
            field.setAccessible(true);
            Object bean = this.applicationContext.getBean(sv.beanClass()); // 得到bean(UserDao)
            // bean中找到方法 ---find方法
            Method method = sv.beanClass().getMethod(sv.method(),clazz.getDeclaredField(sv.param()).getType());
            // customerId
            Field paramField = clazz.getDeclaredField(sv.param());
            paramField.setAccessible(true);

            Field targetField = null;
            Boolean needInnerField = StringUtils.isNotEmpty(sv.targetField());
            String keyPrefix = sv.beanClass()+"-"+sv.method()+"-"+sv.targetField()+"-";
            for (Object obj:col) {
                Object paramValue = paramField.get(obj); // 3
                if (paramValue == null) continue;
                Object value = null;
                String key = keyPrefix;
                if (cache.containsKey(key)){
                    value = cache.get(key);
                }else {
                    value = method.invoke(bean,paramValue);  // User == value
                    if (value != null){
                        if (needInnerField){
                            if (targetField == null){
                                targetField = value.getClass().getDeclaredField(sv.targetField());

                            }
                            value = targetField.get(value);  // user中的名字tony
                        }
                    }

                    cache.put(key,value);
                }

                field.set(obj,value); //field ---customerName
            }

            // 参数具体的值
            // method.invoke();
        }
    }


}
package com.example.hello;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@EnableEurekaClient
@RestController
public class ServiceHelloApplication {

	public static void main(String[] args) {
		SpringApplication.run(ServiceHelloApplication.class, args);
	}
	@Value("${server.port}")
	String port;

	@RequestMapping("/hello")
	public String home(@RequestParam(value = "name", defaultValue = "toher") String name) {
		return "hi " + name + " ,this is Feign Project , i am from port:" + port;
	}

}

项目结构:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值