Welcome to pay attention to the public number “Java fish”, more knowledge points you deserve to have

The opening

A middle-aged man wearing a blue shirt, jeans, holding a white thermos cup is sitting in a hurry opposite you, it seems that the project is very urgent, I guess the interview time will not be too long, so I feel relaxed a lot…… (Then I got punched in the face)

The interview began

Interviewer: Young man, I see on your resume that you are proficient in Java, right? Let me ask you a few questions about Java.

Ok, ok, the interviewer asks. (a simple two words to hear the heart secretly pleased……)

Interviewer: Do you know there is a thing called proxy in Java?

You know, the agent is to access the actual target object through the agent object, for example, we rent a house in life, we can directly find the landlord, or through some rental platform to rent a house, through the rental platform this way is the agent. In Java, such a rental platform is called a proxy class, which not only implements the target object, but also adds some additional functionality. As far as I know, there are static proxy and dynamic proxy in Java. (There is a high probability that the interviewer will ask you about both types of agency.)

Interviewer: I didn’t expect you to be able to understand code through phenomena in your life. Good

A static proxy is a class that exists before the code runs. For example, in the code, we will first create a generic interface for renting:

public interface Room {
    void rent();
}
Copy the code

Then you need a proxied class (or real class) and a proxy class:

public class RealRoom implements Room { private String roomname; public RealRoom(String roomname) { this.roomname = roomname; } public void rent() {system.out.println (" rent "+roomname); }}Copy the code

The proxy classes are as follows:

public class ProxyClass implements Room { RealRoom realRoom; public ProxyClass(RealRoom realRoom) { this.realRoom = realRoom; } public void rent() {system.out.println (" rent "); realRoom.rent(); System.out.println(" rent after charge "); }}Copy the code

A proxy class can add functionality without changing the promenade object. Finally, let’s test this static proxy:

Public class Main {public static void Main (String[] args) {RealRoom RealRoom =new RealRoom(" RealRoom "); ProxyClass proxyClass=new ProxyClass(realRoom); proxyClass.rent(); }}Copy the code

Then observe the results:

Charge agency fee before renting a house. Charge service fee after renting a house from Country GardenCopy the code

Interviewer: Since static agents are so powerful, what are their disadvantages?

Because static proxies already exist before the code runs, a proxy class needs to be created for each proxy object. When there are many proxy objects, many proxy classes need to be created, seriously reducing the maintainability of the program. Dynamic proxies can solve this problem.

Interviewer: Tell me about dynamic agents

Dynamic proxy means that the proxy class is not written in the code, but generated during the running process. Java provides two ways to implement dynamic proxy, namely dynamic proxy based on Jdk and dynamic proxy based on Cglib.

Interviewer: DYNAMIC proxy based on JDK I forgot, you give me a review.

(I?? Implementing the Jdk’s dynamic proxy requires implementing the InvocationHandler interface and then implementing its Invoke method. If the broker’s method is invoked, the broker notifies and forwards it to invoke, the internal InvocationHandler implementation class, which processes the content.

public class ProxyHandler implements InvocationHandler { Object object; public ProxyHandler(Object object) { this.object = object; Public Object invoke(Object proxy, method method, Object[] args) throws Throwable {system.out.println (" before proxy execution: "+method.getName()); Object invoke = method.invoke(object, args); System.out.println(" after agent execution: "+method.getName()); return invoke; }}Copy the code

The dynamic proxy is then performed in the main method

Public static void main(String[] args) {Room =new Room(" RealRoom "); public static void main(String[] args) {Room =new RealRoom(" RealRoom "); //obj.getClass().getClassLoader() //obj.getClass().getinterfaces () object InvocationHandler InvocationHandler invocationHandler=new ProxyHandler(room); Room proxyRoom = (Room) Proxy.newProxyInstance(room.getClass().getClassLoader(), room.getClass().getInterfaces(), invocationHandler); proxyRoom.rent(); }Copy the code

The core of this code is proxy.newProxyInstance, which is intended to generate a Proxy class at run time and finally execute the proxied method through the Proxy class. The final result is as follows:

Before agent execution: Rent rents Country Garden After agent execution: RentCopy the code

Interviewer: Now that you say that, I remember the dynamic agent. What are his advantages?

When I talked about static proxies earlier, I said that the disadvantage of static proxies is that for every object being propped, you need to create a proxy class. The static proxy is written before the project runs. This is not the case with dynamic proxies, which only need to write a dynamic proxy class because the proxy class is created at run time. For example, if I create a proxy object to sell a house:

Write a generic interface, Sell

public interface Sell {
    void sellRoom();
}
Copy the code

Write the class of the proxied object again:

Public class RealSell implements Sell {public void sellRoom() {system.out.println (" RealSell "); }}Copy the code

The dynamic proxy is then performed in the main method

    public static void main(String[] args) {
        Sell sell=new RealSell();
        InvocationHandler invocationHandler=new ProxyHandler(sell);
        Sell proxysell= (Sell) Proxy.newProxyInstance(sell.getClass().getClassLoader(),sell.getClass().getInterfaces(),invocationHandler);
        proxysell.sellRoom();
    }
Copy the code

The final results are as follows:

Before agent execution: sellRoom Sells the house. After agent execution: sellRoomCopy the code

With dynamic proxy, I can proxy multiple objects from a single dynamic proxy class.

Interviewer: If I remember correctly, this way can only proxy interfaces, I see your above examples are also proxy interfaces, so what should I do if I want to proxy classes?

JDK dynamic proxies can really only proxy interfaces. JDK dynamic proxies are based on interfaces; in other words, both the proxy class and the target class implement the same interface. If you want a proxy class, you can use CGLib. A CGLib dynamic proxy is a method by which a proxy class inherits and then implements the target class.

Create a target class, CGRoom

Public class CGRoom {public void rent(String groom name){system.out.println (" groom name "+roomName); }}Copy the code

Create a cglib dynamic proxy class that inherits MethodInterceptor and implements its Intercept method

public class MyMethodInterceptor implements MethodInterceptor { public Object intercept(Object o, Method method, {system.out.println (" before the proxy is executed: "+method.getName()); Object object=methodProxy.invokeSuper(o,objects); System.out.println(" after agent execution: "+method.getName()); return object; }}Copy the code

Finally, the proxy class is created through the Enhance object

Public static void main(String[] args) {public static void main(String[] args) {public static void main(String[] args) {public static void main(String[] args) {public static void main(String[] args) { // Set the bytecode file for the target class, enhancer.setsuperclass (cnetw.class); // Set the callback function enhancer.setCallback(new MyMethodInterceptor()); CGRoom proxy= (CGRoom) enhancer.create(); Proxy. Rent (" country Garden "); }Copy the code

Finally achieve the following results:

Before agent execution: Rent rents Country Garden After agent execution: RentCopy the code

Interviewer: Since dynamic agent is so awesome, do you use it in your daily work?

Although I rarely use dynamic proxy in my business code, I use dynamic proxy in AOP of Spring series framework and RPC framework in my work. Take AOP as an example, AOP enhances the target object through dynamic proxy, such as pre-notification, post-notification and so on, which we most commonly use.

Interviewer: Good! Here are a few basics to test you again, talk about your understanding of annotation, annotation and solve what problems?

Classes, methods, variables, parameters, and packages in the Java language can be marked with annotations, and we can get the corresponding annotations and the content defined in the annotations during application execution. For example, if you detect in Spring that your class is marked with the @Component annotation, The Spring container manages this class for itself at startup, so you can inject the object via the @AutoWired annotation.

Interviewer: Do you know how to define annotations yourself?

There are four main steps to customize annotations:

The first step is to declare an annotation via @interface:

public @interface Myannotation {
    String key() default "";
}
Copy the code

Step 2: use the four meta-annotations :(just say these during the interview)

There are four meta-annotations in Java, namely @target, @Retention, @Documented, and @Inherited. Here are the four types of annotations:

@target: Target specifies the range of objects that the annotation modifies. Values include:

  1. Used to describe a constructor

  2. Describe attributes

  3. Used to describe local variables

  4. Used to describe methods

  5. Describe packages

  6. Describe parameters

  7. Used to describe classes, interfaces (including annotation types), or enum declarations

@retention: Retention defines the Retention scope of the note. The values are:

  1. Valid in the source file (i.e., source retained)

  2. Valid in a class file (i.e., class reserved)

  3. Valid at run time (i.e., run time reserved)

Documented: Documented Indicates that other types of annotations should be considered a public API for the annotated program member and therefore Documented by a tool such as Javadoc. Documented is a marked annotation that has no member.

@Inherited: A Inherited meta-annotation is a markup annotation. @Inherited explains that an annotated type is Inherited. If an annotation type with the @Inherited annotation is applied to a class, the annotation will be applied to a subclass of that class.

@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Myannotation {
    String key() default "";
}
Copy the code

The third step is to use an annotation. Since MEHTOD and FIELD were defined when Target was defined, you can use this annotation in properties and methods:

public class MyannotationTest {
    @Myannotation(key = "javayz")
    private String username;
}
Copy the code

The fourth step uses reflection to parse annotations

public static void main(String[] args) { Class myclass=MyannotationTest.class; Field[] fields = myclass.getDeclaredFields(); For (Field Field: fields) {if (Field. IsAnnotationPresent (Myannotation. Class)) {System. Out. Println (" configure custom annotation "); Myannotation annotation = field.getAnnotation(Myannotation.class); System.out.println(" property: "+field.getName()+" +annotation.key()); }}}Copy the code

Output result:

Custom annotation attributes are configured: The annotation key of username is JavayzCopy the code

Interviewer: I see you mentioned reflex in step 4 above? Tell me what reflection is and what its characteristics are:

JAVA reflection mechanism is in the running state, for any class, can know all the properties and methods of the class; For any object, you can call any of its methods and properties; This ability to dynamically retrieve information and invoke methods on objects is called the Reflection mechanism of the Java language.

In step 4 above analytical annotation of reflection, I through MyannotationTest capturing the class MyannotationTest class object, and using myclass. GetDeclaredFields (); All attributes are retrieved. That’s reflection.

The end of the

Interviewer: Good, you’ve passed the basics, and now I’m going to start the real technical interview!

My god! Unexpectedly this is just the beginning, fortunately I pay attention to the public number “Java fish”, every day in the subway bus can learn knowledge points!