Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
Proxy refers to the use of proxy objects instead of accessing other objects. To put it simply, the intermediary you are looking for in your job search is a proxy.
Static agent
The first thing we need to know is, what is a static proxy? Static proxy refers to the enhancement of the target object’s methods at compile time, for example:
public class TestDemo {
interface EmailService {
void sendEmail(String emailContent);
}
static class EmailServiceImpl implements EmailService{
@Override
public void sendEmail(String emailContent) {
System.out.println("Sent an email saying:"+ emailContent); }}public static void main(String[] args) {
EmailService emailService = new EmailServiceImpl();
emailService.sendEmail("hello"); }}Copy the code
Now if you want to get the current time before sending an email, you can augment the method of sending an email with a proxy class:
public class TestDemo {
interface EmailService {
void sendEmail(String emailContent);
}
static class EmailServiceImpl implements EmailService{
@Override
public void sendEmail(String emailContent) {
System.out.println("Sent an email saying:"+ emailContent); }}static class EmailProxy implements EmailService{
private final EmailService emailService;
public EmailProxy(EmailService emailService) {
this.emailService = emailService;
}
@Override
public void sendEmail(String emailContent) { System.out.println(LocalDateTime.now()); emailService.sendEmail(emailContent); }}public static void main(String[] args) {
EmailService emailProxy = new EmailProxy(new EmailServiceImpl());
emailProxy.sendEmail("hello"); }}Copy the code
The disadvantages of static proxy are very obvious, writing trouble, and scalability is not strong, and the emergence of dynamic proxy, will completely solve these problems.
A dynamic proxy
Dynamic proxy is the opposite of static proxy. Dynamic proxy is to enhance a method of the target object at runtime, such as the service that still sends mail. Dynamic proxy can be implemented like this:
public class TestDemo {
interface EmailService {
void sendEmail(String emailContent);
}
static class EmailServiceImpl implements EmailService {
@Override
public void sendEmail(String emailContent) {
System.out.println("Sent an email saying:"+ emailContent); }}public static void main(String[] args) {
EmailService emailService = new EmailServiceImpl();
EmailService emailProxy = (EmailService) Proxy.newProxyInstance(EmailServiceImpl.class.getClassLoader(), EmailServiceImpl.class.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(LocalDateTime.now());
Object result = method.invoke(emailService, args);
returnresult; }}); emailProxy.sendEmail("hello"); }}Copy the code
Dynamic proxies can be easily implemented using the Proxy and InvocationHandler classes provided by the JDK, but this approach has a limitation: the enhanced class must implement an interface, since Proxy parameters need to receive the class’s interface information.
CGLib implements dynamic proxies
CGLib broke the ice. With CGLib, you can enhance any object method, even if you don’t implement any interface, because it is enhanced by inheritance. Here’s how to use CGLib, first introducing dependencies:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
Copy the code
The implementation is as follows:
public class TestDemo {
static class EmailServiceImpl {
public void sendEmail(String emailContent) {
System.out.println("Sent an email saying:"+ emailContent); }}public static void main(String[] args) {
EmailServiceImpl emailService = new EmailServiceImpl();
EmailServiceImpl emailProxy = (EmailServiceImpl) Enhancer.create(emailService.getClass(), new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println(LocalDateTime.now());
Object obj = methodProxy.invokeSuper(o, args);
returnobj; }}); emailProxy.sendEmail("hello"); }}Copy the code
It is written in a similar way to what the JDK provides, enhancing an object through the create() method of the Enhancer Class, passing in the object’s Class object and an implementation Class for the MethodInterceptor interface, and enhancing the original method in the Intercept () method.