dao、service包下的文件用于实现ioc和di的测试类
bean下的是读取上下文扫描自定义注解
anno下是自定义@Bean和@Autowired 的注解
/**
* bean管理注解模拟@Service注解
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DemoBean {
}
/**
* 依赖注入模拟@Autowired
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DemoDi {
}
/*
* 上下文接口
*/
public interface ApplicationContext {
Object getBean(Class clazz);
}
public class IOCApplicationContext implements ApplicationContext {
private Map beanMap = new HashMap<>();
private static String rootPath = null;
@Override
public Object getBean(Class clazz) {
return beanMap.get(clazz);
}
/**
* 创建有参构造,设置扫描规则
* 当前包以及子包,哪些类有@DemoBean注解,使用反射实例化并添加到beanMap中
*/
public IOCApplicationContext(String scanPackage) {
if (StringUtils.isEmpty(scanPackage)) {
throw new RuntimeException("包路径不能为空");
}
try {
// 1、将包路径转换成文件路径(com.learn.boot.ioc --->com/learn/boot/ioc)
String packagePath = scanPackage.replaceAll("\\.", "\\\\");
// 2、获取绝对路径
Enumeration resources = Thread.currentThread().getContextClassLoader().getResources(packagePath);
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
// 将url 转码
String path = URLDecoder.decode(url.getFile(), "UTF-8");
if (rootPath == null) {
rootPath = path.substring(0, path.length() - packagePath.length());
}
// 包扫描
scanBean(new File(path));
}
scanDi();
} catch (Exception e) {
e.printStackTrace();
}
}
private void scanDi() {
// 遍历beanMap
beanMap.forEach((k, v) -> {
Class> clazz = v.getClass();
// 获取所有属性
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
// 判断属性上是否存在@DemoDi注解
DemoDi annotation = field.getAnnotation(DemoDi.class);
if (null != annotation) {
// 如果是私有属性,需要开启设置
field.setAccessible(true);
// 如果有,则匹配设置
try {
// v 当前对象,要设置的值
field.set(v,beanMap.get(field.getType()));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
});
}
/**
* 包扫描
*
* @param file
*/
private void scanBean(File file) throws Exception {
// 判断是否是文件夹.否,直接返回
if (file.isDirectory()) {
// 获取文件夹内容
File[] files = file.listFiles();
// 为空直接返回
if (files == null || files.length == 0) {
return;
}
// 不为空遍历数据
for (int i = 0; i < files.length; i++) {
File f = files[i];
// 如果还存在内容,递归获取数据
if (f.isDirectory()) {
// 递归继续获取
scanBean(f);
} else {
// 如果是文件则判断是否是class,如果是则将\转换为.,并去掉.class
String absolutePath = f.getAbsolutePath();
if (absolutePath.endsWith(".class")) {
String pathClass = absolutePath.substring(rootPath.length() - 1);
// 替换并截取,得到文件路径:com.learn.boot.ioc.service.impl.DemoServiceImpl
String className = pathClass.replaceAll("\\\\", "\\.").replace(".class", "");
// 通过反射获取对象
Class> clazz = Class.forName(className);
// 判断是否是接口,否则需要实例化
if (!clazz.isInterface()) {
// 是则判断存在@DemoBean注解
DemoBean annotation = clazz.getAnnotation(DemoBean.class);
// 如果annotation != null,当前类上有注解
if (annotation != null) {
// 实例化
Object o = clazz.getConstructor().newInstance();
// 判断当前类是否实现接口,有则使用接口的Class作为key
int length = clazz.getInterfaces().length;
if (length > 0) {
// 如果有实现多个接口,则使用接口的Class作为key
Class>[] interfaces = clazz.getInterfaces();
for (Class> anInterface : interfaces) {
// 存在则添加到Map中
beanMap.put(anInterface, o);
}
} else {
// 没有接口则使用自己的class
beanMap.put(clazz, o);
}
}
}
}
}
}
}
}
public static void main(String[] args) {
IOCApplicationContext iocApplicationContext = new IOCApplicationContext("com.learn.boot.ioc");
IDemoService bean = (IDemoService) iocApplicationContext.getBean(IDemoService.class);
bean.add();
}
}
@DemoBean
public class DemoDaoImpl implements IDemoDao {
@Override
public void test() {
System.out.println("DemoDaoImpl.test.........");
}
}
public interface IDemoDao {
void test();
}
@DemoBean
public class DemoServiceImpl implements IDemoService {
@DemoDi
private IDemoDao demoDao;
@Override
public void add() {
System.out.println("DemoServiceImpl.add......");
demoDao.test();
}
}
public interface IDemoService {
void add();
}
在实现springIOC Di的过程中主要是反射,通过对应的包路径进行扫描添加到容器中,在使用的过程中可直接使用。
动态代理可批量完成统一业务功能,且解耦
动态代理JDK的动态代理和Cglib的动态代理
有接口使用JDK动态代理,代理对象和目标对象实现同样的接口
代理对象返回的是接口
如果没有接口,使用的是cglib动态代理
代理对象返回的是指定类
准备:
两个接口,对应实现类,代理类、测试类
public interface ProxyService {
void create();
void update();
void query();
void delete();
}
public class ProxyServiceImpl implements ProxyService {
@Override
public void create() {
System.out.println("UserServiceImpl.create.......");
}
@Override
public void update() {
System.out.println("UserServiceImpl.update.......");
}
@Override
public void query() {
System.out.println("UserServiceImpl.query.......");
}
@Override
public void delete() {
System.out.println("UserServiceImpl.delete.......");
}
}
public interface UserDemoService {
void create();
void update();
void query();
void delete();
}
public class UserDemoServiceImpl implements UserDemoService {
@Override
public void create() {
System.out.println("--------------UserDemoServiceImpl.create---");
}
@Override
public void update() {
System.out.println("--------------UserDemoServiceImpl.create---");
}
@Override
public void query() {
System.out.println("--------------UserDemoServiceImpl.create---");
}
@Override
public void delete() {
System.out.println("--------------UserDemoServiceImpl.create---");
}
}
public class ServiceProxy {
// 针对所有类
private Object target;
// 有参构造初始化
public ServiceProxy(Object target) {
this.target = target;
}
/**
* 返回代理对象,模拟环绕通知
* @return
*/
public Object getProxy(){
// ClassLoader loader 加载动态生成代理类的类加载器(目标类加载器)
// Class>[] interfaces 目标对象实现的所有接口
// InvocationHandler h 调用处理器
Class> clazz = target.getClass();
System.out.println("----clazz:"+clazz);
ClassLoader classLoader = clazz.getClassLoader();
System.out.println("----classLoader:"+classLoader);
Class>[] interfaces = clazz.getInterfaces();
System.out.println("----interfaces:"+interfaces);
InvocationHandler handler = (proxy, method, args) ->{
String name = method.getName();
System.out.println("【日志】-"+name+"-【调用前执行】-------"+args);
Object invoke = method.invoke(target, args);
System.out.println("【日志】-"+name+"-【调用后执行】-------"+args);
return invoke;
};
Object o = Proxy.newProxyInstance(classLoader, interfaces, handler);
return o;
}
}
测试:
public class TestProxy {
public static void main(String[] args){
ServiceProxy serviceProxy = new ServiceProxy(new ProxyServiceImpl());
ServiceProxy userProxy = new ServiceProxy(new UserDemoServiceImpl());
ProxyService proxy = (ProxyService) serviceProxy.getProxy();
proxy.create();
UserDemoService proxy1 =(UserDemoService) userProxy.getProxy();
proxy1.create();
}
}
结果:
// 创建拦截器实现MethodInterceptor
public class ProxyInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("------cglib----------start-----");
Object invoke = methodProxy.invokeSuper(o, objects);
System.out.println("------cglib----------end-----");
return invoke;
}
}
// 要代理的目标对象
public class UserDemoServiceImpl {
public void create() {
System.out.println("--------------UserDemoServiceImpl.create---");
}
public void update() {
System.out.println("--------------UserDemoServiceImpl.create---");
}
public void query() {
System.out.println("--------------UserDemoServiceImpl.create---");
}
public void delete() {
System.out.println("--------------UserDemoServiceImpl.create---");
}
}
// 测试
public class TestProxy {
public static void main(String[] args){
// ServiceProxy serviceProxy = new ServiceProxy(new ProxyServiceImpl());
// ProxyService proxy = (ProxyService) serviceProxy.getProxy();
// proxy.create();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserDemoServiceImpl.class);
enhancer.setCallback(new ProxyInterceptor());
UserDemoServiceImpl o = (UserDemoServiceImpl) enhancer.create();
o.create();
}
}
结果