在学习使用Spring Boot框架时候,发现了一个特别的现象
UserMapper是一个接口,在另一个类中好像直接使用@Autowired装配了一个UserMapper对象???我纳闷了一会儿,接口居然可以直接实例对象吗?
根据我对的Java基础知识的了解,接口和抽象类都只是描述了一个轮廓、实现,不能直接作为一个对象去实例化使用的,都需要具体的类去继承和实现。
后来查阅资料才知道,接口确实是不能直接实例化的!要想使用接口作为对象,需要用到匿名内部类,及就是在多线程编程中经常使用的那个..
实现接口的匿名内部类
多线程中我们经常会实例一个继承Thread的匿名内部类:
class MyThread extends Thread {
@Override
public void run() {
System.out.println("继承Thread, 重写run");
}
}
这里就是使用{}大括号,在大括号中直接重写必要的方法,然后形成一个匿名内部类。
当然这里的Thread并不是一个抽象类也不是一个接口,但是道理是相同的。
我们只要在创建实现接口的匿名内部类时候,在大括号{}中实现接口的所有方法即可。
创建一个测试接口:
public interface ITest {
public String test();
}
然后在一个类中尝试创建”ITest对象“
其实在尝试new的时候IDEA已经给了你提示(需要通过{}来创建匿名内部类)了,根据提示敲下enter就会得到:
public class Test {
private ITest iTest = new ITest() {
@Override
public String test() {
return null;
}
};
}
所以小结就是,”接口对象“这个说法是错误的!
本质上也没有接口对象,但是有实现接口的匿名内部类。
而最开始展示的Spring Boot中使用@Autowired注解,构建了一个”接口对象“,实际上只是Spring Boot内部隐藏了实现接口并创建匿名内部类的过程和样子,留下像是自动装配接口对象的样子。
写到这里已经开始感慨自己基本功有点不扎实了..其实要是匿名内部类学的够清晰应该也不至于对这个所谓的”接口对象“产生这么大的疑惑。
@Mapper的功能之一
不过我又发现了一个问题。我理解的@Autowired功能是将Spring IoC容器中构建好的对象在需要的时候注入进去,而这是需要配合五大类注解如@Component、@Configuration这些来使用的。
使用类注解注释的类才能被自动装配,否则会报异常(Spring中找不到对应的Bean,忘记叫什么exception了)。
而最开始的接口我并没有使用类注解进行注释,而是使用@Mapper来进行注释的。
所以我对@Mapper的理解也是相当匮乏..我最初只是觉得它是标识映射器,用来连接与接口对应的xml和数据库的。
查阅资料知道,@Mapper能够给接口自动生成一个实现类(匿名内部类),并且将这个类托管给Spring进行管理。这也就印证了为啥可以在接口头上使用@Autowired了..