1.1什么是IOC容器? IOC即控制反转,把传统上由程序代码直接操控的对象转交给容器,通过容器来对组件进行装配和管理,即控制权由程序代码本身转交给了IOC容器来进行管理。
1.2IOC的作用 ①管理对象的依赖创建和维护 ②解耦,容器来管理和维护对象 ③无需关心类的创建过程,直接使用
1.3IOC的优点 ①IOC或依赖注入把应用的代码量降到最低 ②容易进行测试 ③将对象组件之间的耦合降到最低 ④支持懒汉式和饿汉式选择创建
1.4IOC的实现机制 实现原理为工厂模式和代理模式
1.5IOC支持的功能 ①依赖注入 ②依赖检查 ③自动装配 ④支持集合 ⑤指定初始化方法和销毁方法 ⑥支持回调某些方法(但是需要实现 Spring 接口,略有侵入)
2.1什么是Spring的依赖注入? 依赖注入更加准确的描述了IOC的设计理念,容器动态的将有依赖关系的对象注入到所需要它的对象中,让容器根据我们提供的依赖关系进行注入
2.2依赖注入的基本原则 容器全权负责组件的装配,它会把符合依赖关系的对象通过属性(JavaBean中的setter)或者是构造器传递给需要的对象
2.3依赖注入的实现方式 ①使用属性的setter方法注入 ,这是最常用的方式; ②使用构造器注入; ③使用Filed注入(用于注解方式)
2.3.1setter方法注入
public class Car { private String brand; public String getBrand() { return brand; } //一定要写被注入对象的set方法 public void setBrand(String brand) { this.brand = brand; } public void run(){ System.out.println("brand:"+brand+",maxSpeed:"+maxSpeed+",price:"+price); } } <!-- 属性注入 --> <bean id="car" class="com.spring.model.Car"> <property name="brand" value="红旗CA72"></property> </bean> public void test(){ //读取配置文件 ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); //获取bean的实例 Car car=(Car) ctx.getBean("car"); car.run(); }2.3.2构造器注入
public class Car { private String brand; //带参构造方法 public Car(String brand){ this.brand=brand; } public void run(){ System.out.println("brand:"+brand+",maxSpeed:"+maxSpeed+",price:"+price); } } ①按类型匹配入参 <!-- 构造函数注入(按类型匹配) --> <bean id="car1" class="com.spring.model.Car"> <constructor-arg type="java.lang.String" value="宝马"></constructor-arg> </bean> ①按索引匹配入参 <!-- 构造函数注入(按索引匹配) --> <bean id="car2" class="com.spring.model.Car"> <!-- 注意索引从0开始 --> <constructor-arg index="0" value="中国一汽"></constructor-arg> </bean>2.3.3.使用字段(Filed)注入(用于注解方式) 不使用注解注入
<bean id="commonDao" class="com.spring.dao.impl.CommonDaoImpl"></bean> <bean id="commonService" class="com.spring.service.impl.CommonServiceImpl"> <!-- 注入持久化访问所需的DAO组件 --> <property name="commonDao" ref="commonDao"/> </bean>byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。
byType:通过参数的数据类型进行自动装配。
在commonDao和commonService也要加上@Repository和@Service注解,xml中添加扫描(此处省略) @Resource(name = "accountDao1") //默认是按照名称来装配注入的,找不到名称按类型注入 private AccountDao accountDao; @Autowired //默认是按照类型装配注入的 private AccountDao accountDao; @Autowired //默认是按照类型装配注入的 @Qualifier("accountDao1") //指定应该装配哪个确切的 bean 来消除歧义 private AccountDao accountDao;3.1什么是AOP ①aop是面向切面编程,不同于原始的oop是面向对象编程,使用aop可以实现不需要修改源代码,只用修改一些配置便可以实现功能的拓展 ②减少了代码量 ③运行期间通过代理的方式向目标类植入代码 ④运用场景有事务管理,缓存,性能监控,日志和安全检查等 3.2AOP的动态代理有哪些 JDK动态代理要比cglib代理执行速度快,但性能不如cglib好。所以在选择用哪种代理还是要看具体情况,一般单例模式用cglib比较好 ①JDK动态代理
/** * CGLIB代理 */ public class CGLIBProxy implements MethodInterceptor { public Object targetObject; public Object createProxyInstance(Object targetObject){ this.targetObject=targetObject; Enhancer enhancer = new Enhancer(); //设置代理目标 enhancer.setSuperclass(targetObject.getClass()); //设置回调 enhancer.setCallback(this); return enhancer.create(); } /** * 在代理实例上处理方法调用并返回结果 * @param object : 代理类 * @param method :被代理的方法 * @param args :该方法的参数数组 * @param methodProxy */ @Override public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object result = null; try { System.out.println("前置处理开始 ..."); result = methodProxy.invoke( targetObject , args);//执行目标对象的方法 System.out.println("后置处理开始 ..."); } catch (Exception e) { System.out.println("异常处理 ..."); } finally { System.out.println("调用结束 ..."); } return result; } }②cglib代理
/** * 动态代理 */ public class Creatproxy implements InvocationHandler { //创建被代理的对象 private Object target; //创建代理对象的方法 public Object creatprexy(Object target){ this.target=target; //target.getClass().getInterfaces()得到被代理对象的接口,当前创建代理对象类Creatproxy的对象 Object proxy= Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces() ,this ); return proxy; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("想要找一份高薪的程序员工作"); method.invoke(target,args); System.out.println("成功录取,从此走上人生巅峰"); return null; } }