注解配置
为什么要使用注解配置完成 Ioc 和 DI?
虽然xml配置形象,但是随着项目变大这样配置太过繁琐了,所以就有了ioc和DI思想,而这个思想是由Spring来实现的,在我们以后开发中,不再需要去配置一堆没有任何技术含量的bean,我们就需要在对应的字段上贴注解,让spring来帮我们完成对象的创建和注入
DI 注解
Spring的Autowire,JavaEE的Resource,两者作用是一样,完成属性或字段的注入,注入是 bean(取代 XML property ref 元素),贴类中setter 方法或者字段上
@Value 取代注入常量值 贴类中setter 方法或者字段上
Autowired注解使用
Resource注解使用
IoC 注解
@Repository:用于标注数据访问组件,即DAO实现类上。
@Service:用于标注业务层实现类上。
@Controller:用于标注控制层类上(如SpringMVC的Controller)。
@Component:当不是以上的话,可以使用这个注解进行标注。
四个注解的功能是相同的,只是用于标注不同类型的类上。
IoC注解使用
@Component 不写 value 值的话,bean 名字就类名首字母小写,上面列子就是 bean 的名字就是 person。
Scope和PostConstruct以及PreDestroy注解
@Scope: 贴在类上,标明 bean 的作用域。
@PostConstruct: 贴在方法上,标明 bean 创建完后调用此方法。
@PreDestroy : 贴在方法上,标明容器销毁时调用此方法。
使用Scope和PostConstruct以及PreDestroy注解
代理模式
好处
客户端直接使用的都是代理对象,不知道真实对象是谁,此时代理对象可以在客户端和真实对象之间起到中介的作用。
- 代理对象完全包含真实对象,客户端使用的都是代理对象的方法,和真实对象没有直接关系;
- 代理模式的职责:把不是真实对象该做的事情从真实对象上撇开—职责分离。
静态代理
静态代理:在程序运行前就已经存在代理类的字节码文件,代理对象和真实对象的关系在运行前就确定了。(即代理类及对象要我们自己创建)
类体系图
优缺点
-
优点
业务类只需要关注业务逻辑本身,保证了业务类的重用性。
把真实对象隐藏起来了,保护真实对象。
-
缺点
随着项目变大,代理类太多
动态代理
可以解决静态代理的问题
JDK动态代理API
JDK动态代理API
-
java.lang.reflect.Proxy类
Java 动态代理机制生成的所有动态代理类的父类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。
主要方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandlerhanlder)
方法职责:为指定类加载器、一组接口及调用处理器生成动态代理类实例
参数:
loader :类加载器,一般传递真实对象的类加载器 interfaces:代理类需要实现的接口 handler:代理执行处理器,说人话就是生成代理对象帮你要做什么
返回:创建的代理对象
-
java.lang.reflect.InvocationHandler 接口
主要方法:public Object invoke(Object proxy, Method method, Object[] args)
方法职责:负责集中处理动态代理类上的所有方法调用,让使用者自定义做什么事情, 对原来方法增强(加什么功能)。
参数:
proxy :生成的代理对象
method:当前调用的真实方法对象
args :当前调用方法的实参
返回:真实方法的返回结果
类体系及调用流程
CGLIB动态代理
JDK动态代理的问题
JDK动态代理要求真实类必须实现接口。而CGLIB与JDK动态代理不同是,真实类不用实现接口,生成代理类的代码不一样且代理类会继承真实类。
CGLIB动态代理API
-
org.springframework.cglib.proxy.Enhancer
类似JDK中Proxy,用来生成代理类创建代理对象的。
-
org.springframework.cglib.proxy.InvocationHandler
类似JDK中InvocationHandler,让使用者自定义做什么事情,对原来方法增强。
类体系及调用流程
优缺点
-
优点
对比静态代理,发现不需手动地提供那么多代理类。
-
缺点
API 确实难用,若 Spring 的话的配置也恶心,真对不同方法区分要做判断等等