- 定义一个接口,两个实现类
package com.my.spi;
public interface ISpiMyService {
String getSpiServiceName(String serviceName);
}
package com.my.spi.impl;
import com.my.spi.ISpiMyService;
public class SpiMyMessageJobServiceImpl implements ISpiMyService {
public String getSpiServiceName(String serviceName) {
return this.getClass().getCanonicalName()+"---"+serviceName;
}
}
package com.my.spi.impl;
import com.my.spi.ISpiMyService;
public class SpiMyQueryJobServiceImpl implements ISpiMyService{
public String getSpiServiceName(String serviceName) {
return this.getClass().getCanonicalName()+"---"+serviceName;
}
}
- 配置SPI文件路径,添加实现类包名+类名
com.my.spi.impl.SpiMyMessageJobServiceImpl
com.my.spi.impl.SpiMyQueryJobServiceImpl
- 调用接口
package com.my.spi;
import java.util.ServiceLoader;
public class SpiMain {
public static void main(String[] args) {
ServiceLoader<ISpiMyService> services= ServiceLoader.load(ISpiMyService.class);
for(ISpiMyService iSpiMyService:services){
System.out.println(iSpiMyService.getSpiServiceName("我的业务实现类"));
}
}
}
- 执行结果
com.my.spi.impl.SpiMyMessageJobServiceImpl---我的业务实现类
com.my.spi.impl.SpiMyQueryJobServiceImpl---我的业务实现类
- 通过上述spi示例,如果开放接口,基于接口编写新的功能,可以轻松新功能覆盖旧功能
- Springboot启动时候查看注册的bean,并去掉不需要的bean
package com.myspring.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
public class MyConfig implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
//移除注冊的bean
beanDefinitionRegistry.removeBeanDefinition("employeeController");
int count=beanDefinitionRegistry.getBeanDefinitionCount();
String[] beansName=beanDefinitionRegistry.getBeanDefinitionNames();
//輸出beanName
Arrays.asList(beansName).stream().forEach(beanName->System.out.print(beanName));
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
8.自定义注解配合动态代理,给接口中的中法添加制定定义注解,执行接口方法调用
自定义注解
import java.lang.annotation.*;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface SqlCommandType {
SqlType value();
}
定义接口
public interface OrderDao {
@SqlCommandType(value=SqlType.INSERT)
String add(String str);
@SqlCommandType(value=SqlType.UPDATE)
String update(String str);
}
public interface UserDao {
@SqlCommandType(value=SqlType.INSERT)
String add(String str);
@SqlCommandType(value=SqlType.UPDATE)
String update(String str);
}
代理类工厂方法
public class MapperProxyFactory<T> {
private final Class<T> aClass;
public MapperProxyFactory(Class<T> aClass) {
this.aClass = aClass;
}
public Class<T> getMapperInterface(){
return aClass;
}
protected T newInstance(MyInvocationHandler<T> myInvocationHandler){
return (T) Proxy.newProxyInstance(aClass.getClassLoader(),new Class[]{aClass},myInvocationHandler);
}
public T newInstance(){
final MyInvocationHandler<T> myInvocationHandler=new MyInvocationHandler<>(aClass);
return newInstance(myInvocationHandler);
}
}
代理方法
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler<T> implements InvocationHandler,Serializable {
private final Class<T> aClass;
public MyInvocationHandler(Class<T> aClass) {
this.aClass = aClass;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//判断代理类是接口还是对象
if(Object.class.equals(method.getDeclaringClass())){
return method.invoke(this,args);
}
MapperMethod mapperMethod=new MapperMethod(method);
//返回method方法执行的结果
return mapperMethod.execute(args);
}
}
定义代理方法执行逻辑
import java.lang.reflect.Method;
public class MapperMethod {
private final Method method;
public MapperMethod(Method method){
this.method=method;
}
public Object execute(Object[] args){
String msg=method.getDeclaringClass().getCanonicalName()+"."+method.getName()+"("+args[0]+")";
switch (method.getAnnotation(SqlCommandType.class).value()){
case INSERT:
msg="执行插入操作"+msg;
break;
case UPDATE:
msg="执行更新操作"+msg;
break;
default:break;
}
return msg;
}
}
运行程序
public class ProxyMain {
public static void main(String[] args){
MapperProxyFactory<UserDao> userDaoMapperProxyFactory=new MapperProxyFactory<>(UserDao.class);
UserDao target=userDaoMapperProxyFactory.newInstance();
System.out.println(target.add("userDaoInsert"));
System.out.println(target.update("userDaoUpdate"));
MapperProxyFactory<OrderDao> orderDaoMapperProxyFactory=new MapperProxyFactory<>(OrderDao.class);
OrderDao orderDao=orderDaoMapperProxyFactory.newInstance();
System.out.println(orderDao.add("orderAdd"));
System.out.println(orderDao.update("orderUpdate"));
}
}```
执行结果
执行插入操作com.minmax.UserDao.add(userDaoInsert)
执行更新操作com.minmax.UserDao.update(userDaoUpdate)
执行插入操作com.minmax.OrderDao.add(orderAdd)
执行更新操作com.minmax.OrderDao.update(orderUpdate)