কোনও POJO- এ সর্বজনীন সম্পত্তিগুলির জন্য getters / setters প্রতিলিপি করার উপায়


9

আমাদের কাছে একটি POJO রয়েছে যা ~ 60 টি বৈশিষ্ট্য নিয়ে স্বয়ংক্রিয়ভাবে উত্পন্ন। এটি অভ্র 1.4 দিয়ে উত্পাদিত হয়েছে, এতে গ্রাহকরা / সেটটারগুলি অন্তর্ভুক্ত নয়।

আমরা লাইব্রেরি যা অবজেক্টের মধ্যে সহজ রূপান্তর সরবরাহ করতে ব্যবহার করি তার সঠিকভাবে কাজ করার জন্য গিটার / সেটার জাতীয় পদ্ধতি প্রয়োজন।

পিজোকে ম্যানুয়ালি ওভাররাইড না করে এবং গ্রাহকরা / সেটটারগুলির সমস্ত ম্যানুয়ালি তৈরি না করেই গেটার / সেটারগুলি প্রতিলিপি দেওয়ার কোনও উপায় আছে কি?

public class BigGeneratedPojo {
  public String firstField;
  public int secondField;
  ...
  public ComplexObject nthField;
}

public class OtherObject {
  private String reprOfFirstFieldFromOtherObject;
  private ComplexObject reprOfFirstFieldFromOtherObject;
  public String getReprOfFirstFieldFromOtherObject() { ... standard impl ... };
  public void setReprOfFirstFieldFromOtherObject() { ... standard impl ... };
}

আকাঙ্ক্ষা এমন কোড লিখিত হয় যা দেখে মনে হয়:

Mapper<BigGeneratedPojo, OtherObject> mapper = 
  MagicalMapperLibrary.mapperBuilder(BigGeneratedPojo.class, OtherObject.class)
    .from(BigGeneratedPojo::getFirstField).to(OtherObject::reprOfFirstFieldFromOtherObject)
    .build();

BigGeneratedPojo pojo = new BigGeneratedPojo();
pojo.firstField = "test";

OtherObject mappedOtherObj = mapper.map(pojo);

assertEquals(mappedOtherObj.getReprOfFirstFieldFromOtherObject(), "test");

উত্তর:


7

আপনি উদাহরণস্বরূপ, বিটবড্ডি ব্যবহার করে প্রক্সি বিনগুলি গতিশীলভাবে তৈরি করার চেষ্টা করতে পারেন: https://bytebuddy.net/

নীচের নমুনাটি দেখায় যে কীভাবে কোনও পদ্ধতির সম্পত্তি ক্ষেত্রের প্রক্সি করা যায়। নোট করুন যে এটি কেবলমাত্র একটি নমুনা, এবং সম্ভবত আপনাকে এটিকে আবৃত করতে এবং প্রতিচ্ছবি ব্যবহার করে কিছু গতিশীল যুক্ত করতে হতে পারে তবে আমি মনে করি আপনি কোডটি গতিশীলভাবে প্রসারিত করতে চান তবে এটি বেশ আকর্ষণীয় বিকল্প।

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FixedValue;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.jar.asm.Opcodes;
import org.apache.commons.beanutils.BeanUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class M1 {

    public static class PojoBase {
        int property;
        String strProp;
    }



    public static class Intereptor {

        private final String fieldName;
        private final PojoBase pojo;
        public Intereptor(PojoBase pojo, String fieldName) {
            this.pojo = pojo;
            this.fieldName = fieldName;
        }
        @RuntimeType
        public Object intercept(@RuntimeType Object value) throws NoSuchFieldException, IllegalAccessException {

            Field field = pojo.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(pojo, value);
            return value;
        }
    }



    public static void main(String... args) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
            PojoBase origBean = new PojoBase();
            PojoBase destBean = new PojoBase();

            origBean.property = 555666;
            origBean.strProp = "FooBar";

        DynamicType.Builder<Object> stub = new ByteBuddy()
            .subclass(Object.class);

        DynamicType.Builder.MethodDefinition.ReceiverTypeDefinition<Object> dynamic = stub.defineMethod("getProperty", Integer.TYPE, Opcodes.ACC_PUBLIC).intercept(FixedValue.value(origBean.property))
                .defineMethod("setProperty", Void.TYPE, Opcodes.ACC_PUBLIC).withParameters(Integer.TYPE).intercept(MethodDelegation.to(new Intereptor(destBean, "property")))
                .defineMethod("getStrProp", String.class, Opcodes.ACC_PUBLIC).intercept(FixedValue.value(origBean.strProp))
                .defineMethod("setStrProp", Void.TYPE, Opcodes.ACC_PUBLIC).withParameters(String.class).intercept(MethodDelegation.to(new Intereptor(destBean, "strProp")));

        Class<?> dynamicType =     dynamic.make()
                .load(M1.class.getClassLoader())
                .getLoaded();


            Object readerObject = dynamicType.newInstance();
            Object writterObject = dynamicType.newInstance();


            BeanUtils.copyProperties(readerObject, writterObject);
            System.out.println("Out property:" + destBean.property);
            System.out.println("Out strProp:" + destBean.property);
    }



}

10

প্রজেক্ট লম্বোক @ গ্রেটার এবং @ মিষ্টার টীকা সরবরাহ করে যা শ্রেণি পর্যায়ে স্বয়ংক্রিয়ভাবে গিটার এবং সেটার পদ্ধতি উত্পন্ন করতে ব্যবহৃত হতে পারে।

লম্বোকেরও সমান ও হ্যাশকোড পদ্ধতি উত্পন্ন করার ক্ষমতা রয়েছে।

অথবা আপনি @Dataলম্বোক ওয়েবসাইটের অনুযায়ী যা ব্যবহার করতে পারেন :

@ ডেটা সব এখনই একত্র করুন: @ টোস্ট্রিংয়ের জন্য একটি শর্টকাট, @ একালসঅ্যান্ডহ্যাশকোড, সমস্ত ক্ষেত্রের @Getter, সমস্ত চূড়ান্ত নয় এমন ক্ষেত্রগুলিতে @ সেটার, এবং @ প্রয়োজনীয়আর্কস কনস্ট্রাক্টর!

@Data
public class BigGeneratedPojo {
  public String firstField;
  public int secondField;
  ...
  public ComplexObject nthField;
}

1
লম্পোক ব্যবহার করা সহজ এবং দ্রুত সেটআপ করা যায়। এটি একটি ভাল সমাধান।
হেইস রোচ

আমি মনে করি একটি শর্ট-কাট হ'ল সহজ বাস্তবায়ন, সমস্যাটি সমাধান করবে এবং আপনাকে উচ্চ পঠনযোগ্যতাও দেবে
লিওনার্দো রে

4

আপনার সীমাবদ্ধতাগুলি দেওয়া, আমি অন্য কোড উত্পন্ন পদক্ষেপ যুক্ত করব। কীভাবে এটি বাস্তবায়ন করা যায় তা আপনার বিল্ড সিস্টেমের উপর নির্ভর করে (ম্যাভেন / গ্রেডল / অন্য কিছু) তবে জাভা পার্সার বা রোস্টার আপনাকে পছন্দসই গেটার্স / সেটটারগুলির সাহায্যে পার্স করতে BigGeneratedPojo.javaএবং একটি সাবক্লাস তৈরি করতে দেয় এবং BigGeneratedPojoপরিবর্তনগুলি পরিবর্তিত হলে বিল্ড সিস্টেমটি স্বয়ংক্রিয়ভাবে এটি আপডেট করা উচিত ।


1

Eclipse এবং STS এর মতো আইডিইগুলি getters / setters পদ্ধতি যুক্ত করার জন্য বিকল্প সরবরাহ করে। আমরা সেটার / গেটার পদ্ধতি তৈরি করতে সেই বিকল্পগুলি ব্যবহার করতে পারি


সমস্যাটি প্রকৃত পদ্ধতিগুলি লিখছে না। আমি জানি যে কীভাবে এটি ইন্টেলিজে দ্রুত তৈরি করা যায়। সমস্যাটি BigGeneratedPojo উত্পন্ন ফাইল হিসাবে দেখা দেয় , সুতরাং এটির প্রকৃতপক্ষে হেরফের করার জন্য আমার এটি সাবক্লাস করতে হবে এবং একটি র‌্যাপার ক্লাস ডাব্লু / ~ 120 ডামি পদ্ধতি (60 গিটার / সেটার) রাখতে হবে এবং এটি বজায় রাখা দুঃস্বপ্ন।
অ্যান্থনি

1
@ অ্যান্টনি আপনি যখন আইডিই'র সম্পাদকটিতে ফাইলটি খুলবেন, ফাইলটি নিজে হাতে উত্পন্ন হয়েছে বা লিখিত হয়েছে কিনা তা অপ্রাসঙ্গিক। উভয় ক্ষেত্রেই, আপনি একক ক্রিয়া সহ পদ্ধতিগুলি যুক্ত করতে পারেন। আপনি যখন ফাইলটি পুনরায় উত্পন্ন করার পরিকল্পনা করছেন কেবল তখনই এটি কার্যকর হবে না। তবে তারপরে, 60 টি সম্ভাব্য পরিবর্তিত বৈশিষ্ট্য সহ একটি বর্গ থাকা ইতিমধ্যে একটি "বজায় রাখার একটি স্বপ্ন"।
হোলার

1

আমি আপনার ক্লাস থেকে সর্বজনীন ক্ষেত্রগুলি পেতে প্রতিচ্ছবিটি ব্যবহার করার পরামর্শ দেব এবং নীচে আপনার নিজের জাভা প্রোগ্রামটি ব্যবহার করে গেটর এবং সেটটারগুলি তৈরি করুন। উদাহরণ হিসাবে নিম্নলিখিত শ্রেণি বিবেচনা করুন।

import java.lang.reflect.Field;
import java.util.Arrays;

class TestClass {

    private int value;
    private String name;
    private boolean flag;
}

public class GetterSetterGenerator {

    public static void main(String[] args) {
        try {
            GetterSetterGenerator gt = new GetterSetterGenerator();
            StringBuffer sb = new StringBuffer();

            Class<?> c = Class.forName("TestClass");
            // Getting fields of the class
            Field[] fields = c.getDeclaredFields();

            for (Field f : fields) {
                String fieldName = f.getName();
                String fieldType = f.getType().getSimpleName();

                gt.createSetter(fieldName, fieldType, sb);
                gt.createGetter(fieldName, fieldType, sb);
            }
            System.out.println("" + sb.toString());

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    private void createSetter(String fieldName, String fieldType, StringBuffer setter) {
        setter.append("public void").append(" set");
        setter.append(getFieldName(fieldName));
        setter.append("(" + fieldType + " " + fieldName + ") {");
        setter.append("\n\t this." + fieldName + " = " + fieldName + ";");
        setter.append("\n" + "}" + "\n");
    }

    private void createGetter(String fieldName, String fieldType, StringBuffer getter) {
        // for boolean field method starts with "is" otherwise with "get"
        getter.append("public " + fieldType).append((fieldType.equals("boolean") ? " is" : " get") + getFieldName(fieldName) + " () { ");
        getter.append("\n\treturn " + fieldName + ";");
        getter.append("\n" + "}" + "\n");
    }

    private String getFieldName(String fieldName) {
        return fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1, fieldName.length());
    }
}

কোডটি এখান থেকে নেওয়া হয়েছে - অপ্রয়োজনীয় এড়াতে সামান্য পরিবর্তন করা হয়েছেSystem.out । আপনি সহজেই আপনার mainফাংশন থেকে একটি ফাইল তৈরি করতে পারেন এবং সেখানে আপনার গেটার এবং সেটটার স্থাপন করতে পারেন।

আপনি প্রোগ্রামটি এখানে চালিয়ে চেক করতে পারেন । আমি আশা করি এটি সাহায্য করবে.


1

আপনি লম্বোক ব্যবহার করতে পারেন। ব্যবহার এবং প্রয়োগ করা সহজ। এটি ক্লাস ফাইল পোস্ট সংকলনে গেটর এবং সেটার তৈরি করবে। এটি কোডটিকে আরও পরিষ্কার দেখায়।

@Getter @Setter @NoArgsConstructor
public class User implements Serializable {
 private @Id Long id;

private String firstName;
private String lastName;
private int age;

public User(String firstName, String lastName, int age) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
}

}

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.