0

I have a class Teacher which have two variables one is a collection of Student class and another is a Student class Object. I intercept the Teacher class as per my understanding all the objects under the Teacher class should have the interceptor attached to it. so for instance one we call a getter method on the Student variable retrieved from the Teacher class or from the list .It should call the intercept method is not called.This makes our axiom for design false.So my question is : Is there a way we can automatically intercept all the objects declared within the class and this could extend to the further down hierarchy within the tree? Below is the code :

//Teacher class

package com.anz.interceptorproject;
import java.util.ArrayList;
import java.util.List;
/**
 * Created by mehakanand on 4/24/16.
 */public class Teacher {

    private String userName;
    private String cource;
    private List<Student> students=new ArrayList<Student>(  );

    public Student getComplexObjectStudent() {
    return complexObjectStudent;
}

    public void setComplexObjectStudent( Student complexObjectStudent ) {
    this.complexObjectStudent = complexObjectStudent;
}

    private Student complexObjectStudent=new Student();
    public List<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getCource() {
        return cource;
    }

    public void setCource(String cource) {
        this.cource = cource;
    }
}

//Student Class

package com.anz.interceptorproject;

/**
 * Created by mehakanand on 4/24/16.
 */public class Student {

    private String name;
    private int age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

//Interceptor Class
package com.anz.interceptorproject.change;
import java.lang.reflect.*;
import net.sf.cglib.proxy.*;
/**
 * Created by mehakanand on 4/24/16.
 */
public class ClassFacadeCglib implements MethodInterceptor{

    private Object target;

    public Object getInstance(Object target) {
        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        // callback method
        enhancer.setCallback(this);
        // create proxy object
        return enhancer.create();
    }


    public Object intercept(Object obj, Method method, Object[] args,
                            MethodProxy proxy) throws Throwable {
        Object res=null;

        if(method.getName().startsWith("set")){
            System.out.println(method.getName()+" start");
           res = method.invoke(target, args);

            proxy.invokeSuper(obj, args);
            System.out.println(method.getName()+" end..");
        }
        if(method.getName().startsWith("get")){
            System.out.println(method.getName()+" start");
             res = method.invoke(target, args);

            proxy.invokeSuper(obj, args);
            System.out.println(method.getName()+" end");
        }

        return  res;
    }

}

//Delegate class

package com.anz.interceptorproject;

import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;

import net.sf.cglib.proxy.MethodInterceptor;
import org.junit.Test;

public class SimpleUnitTest {
// this test is being used to test if when object is being intercepted will all its child object be intercepted automatically or not
    @Test
    public void TestifchildrenObjectIntercepted() {
        String proxyStudentName="";
        ClassFacadeCglib cglib=new ClassFacadeCglib();

        Student studentMehak=new Student();
        studentMehak.setAge( 30 );
        studentMehak.setName( "Mehak Anand" );
        Student studentComploexproxy=new Student();
        studentComploexproxy.setAge( 23 );
        studentComploexproxy.setName( "proxystudent Complex" );
        //let us assume the Teacher object is an object return from JCR after the adapTo() function is called on a resource
        Teacher teacher=new Teacher();
        teacher.setComplexObjectStudent( studentComploexproxy );
        teacher.getStudents().add( studentMehak );
        teacher.setCource("Math");
        teacher.setUserName("Mehak");
        teacher.getUserName();
        Teacher proxyTeacher=(Teacher)cglib.getInstance(teacher);

      / proxyTeacher.getClass().getDeclaredMethods();
        for (Student proxyStudentList:proxyTeacher.getStudents())
        {
            //the intercept method is not called.
            proxyStudentName= proxyStudentList.getName();
        }
        Student testComplexStudent=teacher.getComplexObjectStudent();
         assertEquals("Math",proxyTeacher.getCource());
        //the intercept method is not called
        testComplexStudent.getAge();

        System.out.println(  teacher.getUserName());

        assertTrue(true);
    }

}

1 Answers1

0

my understanding all the objects under the Teacher class should have the interceptor attached to it. so for instance one we call a getter method on the Student variable retrieved from the Teacher class or from the list .It should call the intercept method

This is not true. Method interceptors are attached only to the object created with enhancer.create(). Any object created with class constructor - such as your Student objects - are not enhanced and thus have no interceptors attached. The one possible solution is to use factory method instead of public constructor to produce enhanced objects:

public class Student {
    protected Student() {
    }

    public static Student getInstance() {
         Enhancer e = new Enhancer();
         // set superclass, interceptors etc here....
         return (Student) e.create();
    }
}
Alex
  • 644
  • 4
  • 10
  • Hi Alex,Thank you .But what if we want to do assigning of the reflection /enhance object at runtime and not at the constructor level.So for instance if we found that a feild is anything apart from regular primary time like a collection or any other class object it should have reflection attached to it. – Mehak Anand May 31 '16 at 12:30