spring - 注册代理类
最近我遇到了一个难题,如下图,禁止任何类继承A这个接口,而程序正常运行,怎么实现?
(换种问法,就是如何实现Mybatis的配置方式)
了解代理模式的,一看就知道,要使用动态代理的知识,但,问题的难点不在这;
难点是要把代理类,注册到Spring容器中,使用@Autowired可以获取到你的代理类。
(注:Spring注册需要的是Class,而不是一个对象实例;但是动态代理获取到的已经是对象实例)
Demo(往Spring容器注册代理类)
工厂类
使用了Cglib提供的代理方式
import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class BeanFactory { /** * 代理方法回调 * * @author ChenSS on 2017年12月21日 */ private class MyInterceptor implements MethodInterceptor { private Class<?> clazz; @Override public Object intercept(Object obj, Method method, Object[] params, MethodProxy proxy) throws Throwable { String methodName = method.getName(); if ("toString".equals(methodName) || "hashCode".equals(methodName)) { return proxy.invokeSuper(obj, params); } try { System.out.println("前置代理"); System.out.println(clazz.getSimpleName() + " " + methodName + " invock"); return null; } catch (Exception e) { System.out.println("异常代理"); return null; } finally { System.out.println("后置代理"); } } } /** * 创建代理类 */ public Object getInstance(Class<?> clazz) throws Exception { System.out.println("======================================"); System.out.println(clazz + " create proxy..."); MyInterceptor callBack = new MyInterceptor(); callBack.clazz = clazz; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback(callBack); Object obj = enhancer.create(); System.out.println("======================================"); return obj; } }
普通类
public interface HelloWorld1 { public void sayHello(); } public interface HelloWorld2 { public void sayHello(); }/** * 使用了Spring注解的Bean * * @author ChenSS on 2017年12月21日 */ @Component public class TestBean { @Autowired HelloWorld1 helloWorld1; public HelloWorld1 getHelloWorld1() { return helloWorld1; } }
Spring配置
注解和Xml混合使用
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <bean id="beanFactory" class="com.client.bean.BeanFactory"/> <bean id="helloWorld1" factory-bean="beanFactory" factory-method="getInstance"> <constructor-arg type="Class"><value>com.client.bean.HelloWorld1</value></constructor-arg> </bean> <bean id="helloWorld2" factory-bean="beanFactory" factory-method="getInstance" lazy-init="true"> <constructor-arg type="Class"><value>com.client.bean.HelloWorld2</value></constructor-arg> </bean> <!-- 自动注入,扫描包 --> <context:component-scan base-package="com.client.bean" /> </beans>
测试函数
import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.client.bean.HelloWorld1; import com.client.bean.HelloWorld2; import com.client.bean.TestBean; public class TestSp { public static void main(String[] args) throws InterruptedException { AbstractApplicationContext context = new ClassPathXmlApplicationContext("classpath:config/spring_context.xml"); //测试@Autowired注入功能 TestBean bean =context.getBean(TestBean.class); HelloWorld1 helloWorld1 = bean.getHelloWorld1(); helloWorld1.sayHello(); //测试懒加载功能 Thread.sleep(2000); System.out.println("Thread wait 2000ms"); HelloWorld2 helloWorld2 = (HelloWorld2) context.getBean("helloWorld2"); helloWorld2.sayHello(); context.close(); } }
实际使用过程中,不一定要全部配写在Xml文件中,直接通过Java代码注册Bean,像Mybatis一样,写一份自动扫描包的方法
疯狂的妞妞 :每一天,做什么都好,不要什么都不做!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY