spring是轻量级的开源JavaEE框架,对javaAPI进行了封装,大大降低了API的使用难度,其核心是IOC和AOP。
IOC(控制反转)在传统的编程中获取对象的方式通常使用new关键字来主动创建一个对象,在spring中,对象的生命周期由IOC容器来管理,直接从容器中获取一个对象,控制权从应用程序交给了IOC容器,对象与对象之间的关系由IOC进行联系。当对象A实例化和运行时,如果需要对象B,IOC容器就会主动创建一个对象B注入到对象A所需的地方,由此,对象A获得依赖对象B的过程,由主动行为变为被动行为,即把创建对象交给IOC容器处理,控制权颠倒过来了,就是所谓的控制反转。
AOP(面向切面编程)在传统的业务处理代码中,通常会进行事务处理,日志记录等操作,虽然采用OOP可以组合或者父子继承的方式达到代码的纵向重用,但相同代码仍会分散到各个方法中,AOP采用横向抽取机制将重复代码提取出来,然后在程序编译或运行时再将这些提取出来的代码应用到所需执行的地方,这种横向抽取的方式即为AOP,AOP是一种新的编程思想但不是OOP的替代品,只是一种延伸和补充。
IOC底层原理:工厂模式,反射
AOP底层原理:动态代理,有接口采用jdk代理,无接口采用cglib代理
(1)如果你使用BeanFactory作为Spring Bean的工厂类,则所有的bean都是在第一次使用该Bean的时候实例化
(2)如果你使用ApplicationContext作为Spring Bean的工厂类,则又分为以下几种情况:
• 如果bean的scope是singleton的,并且lazy-init为false(默认是false,所以可以不用设置),则 ApplicationContext启动的时候就实例化该Bean,并且将实例化的Bean放在一个map结构的缓存中,下次再使 用该 Bean的时候,直接从这个缓存中取
• 如果bean的scope是singleton的,并且lazy-init为true,则该Bean的实例化是在第一次使用该Bean的时候进 行实例化
• 如果bean的scope是prototype的,则该Bean的实例化是在第一次使用该Bean的时候进行实例化
配置xml文件,注解方式
三种 setter方法、p命名空间、构造器方法 1.setter方法
使用setter方法注入,创建类,定义属性和对应的set方法
public class User { private String name; private String age; public void setName(String name) { this.name = name; } public void setAge(String age) { this.age = age; } } }然后在xml文件中配置
<!-- 1.创建对象 class中写类全限定名--> <bean id="user" class="User"> <!-- 2.property标签实现set方式注入--> <property name="name" value="张三"></property> </bean>2.有参构造进行注入
public class User { private String name; private String age; public User(String name, String age) { this.name = name; this.age = age; } public User() { } }xml文件配置
<!-- 1.创建对象--> <bean id="user" class="User"><!-- 2.有参构造注入值 constructor-arg标签--> <constructor-arg name="name" value="张三"></constructor-arg> <constructor-arg name="age" value="26"></constructor-arg> </bean>解释 Spring 支持的几种bean 的作用域。
• singleton : bean 在每个 Spring ioc 容器中只有一个实例。 • prototype:一个 bean 的定义可以有多个实例。 • request:每次 http 请求都会创建一个 bean,该作用域仅在基于 web 的 Spring ApplicationContext 情形下有效。 • session:在一个 HTTP Session 中,一个 bean 定义对应一个实例。该 作用域仅在基于 web 的 Spring ApplicationContext 情形下有效。 • global-session:在一个全局的 HTTP Session 中,一个 bean 定义对应一个实例。该作用域仅在基于 web 的 Spring ApplicationContext 情形下有效。
• Spring 容器 从 XML 文件中读取 bean 的定义,并实例化 bean。 • Spring 根据 bean 的定义填充所有的属性。 • 如果bean 实现了BeanNameAware 接口,Spring 传递bean 的ID 到 setBeanName 方法。 • 如果 Bean 实现了 BeanFactoryAware 接口, Spring 传递beanfactory 给 setBeanFactory 方 法 。 • 如果有任何与 bean 相关联的 BeanPostProcessors,Spring 会在postProcesserBeforeInitialization()方法内调用它们。 • 如果 bean 实现 IntializingBean 了,调用它的 afterPropertySet 方法, 如果 bean 声明了初始化方法,调用此初始化方法。 • 如果有 BeanPostProcessors 和 bean 关联,这些 bean 的postProcessAfterInitialization() 方法将被调用。 • 如果 bean 实现了 DisposableBean,它将调用 destroy()方法。
Spring 支持两种类型的事务管理:
• 编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。 • 声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和 XML 配置来管理事务。
通知是个在方法执行前或执行后要做的动作, 实际上是程序执行时要通过SpringAOP 框架触发的代码段。
Spring 切面可以应用五种类型的通知:
• before:前置通知,在一个方法执行前被调用。 • after: 在方法执行之后调用的通知,无论方法执行是否成功。 • after-returning: 仅当方法成功完成后执行的通知。 • after-throwing: 在方法抛出异常退出时执行的通知。 • around: 在方法执行之前和之后调用的通知。
动态代理是一种方便运行时动态生成代理对象、动态处理代理调用的机制 JDK动态代理:基于java反射机制实现,必须实现接口的业务类才能使用这种方式生成代理对象 动态代理的三个元素: 接口、被代理类(接口实现类)、动态代理类(实际调用被代理类的方法和属性的类) 采用jdk提供的动态代理接口InvocationHandler来实现动态代理类,期中invoke方法是该接口必须实现的方法,它完成对真实方法的调用,通过InvocationHandler接口,所有方法都由该Handler进行处理,即所有被代理方法都由invocationHandler接管实际的处理任务,invoke方法中实现增加自定义的增强功能 接口
package proxy; public interface UserInterface { int add(int a, int b); }代理目标对象(接口实现类)
package proxy; public class UserInterfaceImpl implements UserInterface { @Override public int add(int a, int b) { return a+b; } }代理
package proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class UserProxy { public static void main(String[] args) { Class[] intrefaces = {UserInterface.class}; UserInterfaceImpl user = new UserInterfaceImpl(); UserInterface proxyInstance = (UserInterface) Proxy.newProxyInstance(UserProxy.class.getClassLoader(), intrefaces, new UserHandler(user)); int add = proxyInstance.add(1, 2); System.out.println(add); } } class UserHandler implements InvocationHandler{ private Object object; public UserHandler(Object object){this.object=object;} @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("代理功能模块"); Object o = method.invoke(object, args); return o; } }使用new关键字
使用Class类的newInstance方法
使用Constructor类的newInstance方法
使用clone方法
使用反序列化
Collection接口派生了两个子接口Set和List Set接口 Set接口继承于Collection接口,它没有提供额外的方法,但实现了Set接口的集合类中的元素是无序且不可重复。
特征:无序且不可重复。3、 List接口 List接口同样也继承于Collection接口,但是与Set接口恰恰相反,List接口的集合类中的元素是对象有序且可重复。
特征:有序且可重复。 两个重要的实现类:ArrayList和LinkedList 1.ArrayList特点是有序可重复的 2.LinkedList是一个双向链表结构的。Java反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法
clone() equals() finalize() getClass() hashCode() notify() notifyAll() toString() wait()
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。 ORM(object Relational Mapping对象关系映射) 数据表和实体类属性对应,操作实体类来实现对数据表的操作
#{}是预编译处理,$ {}是字符串替换。 MyBatis在处理#{}时,会将SQL中的#{}替换为?号,使用PreparedStatement的set方法来赋值;MyBatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。
3)使用 #{} 可以有效的防止SQL注入,提高系统安全性。
写sql语句时起别名 在Mapper映射文件中使用resultMap来自定义映射规则 在MyBatis的全局配置文件中开启驼峰命名规则
Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行接口方法所对应的MappedStatement所代表的sql,然后将sql执行结果返回。 Mapper 接口里的方法,是不能重载的
第一种是使用标签,逐一定义数据库列名和对象属性名之间的映 射关系。
第二种是使用 sql 列的别名功能,将列的别名书写为对象属性名。 有了列名与属性名的映射关系后,Mybatis 通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。
支持,原理。。。。。。
