一·概念
一个轻量级的控制反转和面向切面编程的容器框架
二·使用spring的 好处
1.轻量级,2.控制反转,3.面向切面编程,4.作为一个容器框架,可以继承各种优秀的框架,5.事务的管理,6.解耦,简化开发
三·Spring的两大核心
1.面向切面编程(AOP)
AOP,面向切面编程,可以说是对面向对象编程(OOP)的一个补充。在OOP中中引入了封装,继承和多态的概念来建立一个对象的层次结构。OOP允许定义从上到下的一个关系,但是定义左右就显得无能为力。如:日志,事务等功能。因为日志代码水平的而分散在所有对象层次中,但是它与散布到对象的核心功能不存在关系。如果持续使用OOP就会产生大量的重复代码,不利于模块的重用。但是AOP解决了这种情况,它利用一种横切的技术,剖开封装的对象内部,把一些与核心功能无关且常出现到各个对象中的功能单独封装出来。以便于减少代码的重复,降低耦合度,以及提高可操作性和可维护性。
2.控制反转(IOC)
IOC,控制反转 ,简单来说就是复杂的系统看成简单的各个对象间相互合作,但是进行一个封装,内部的复杂实现对外是隐藏了的。
四·AOP的动态代理方式
1.JDK的动态代理
使用情况:目标对象的实现类实现了接口
实现方式:
Java.lang.reflect包中的InvocationHandler接口
public interface InvocationHandler{
public Object invoke(Object proxy,Method method,Object[] args)throws Throwable;
}
proxy:被代理的类的实例
method:调用被代理的类的方法
args:该方法需要的参数
使用方法首先需要实现接口,并且在invoke方法中调用被代理类的方法并且获得返回值,同样也可以在调用前去做事,从而实现动态代理
2.cglib动态代理
使用情况:目标对象的实现类没有实现接口
五·AOP的基本概念
连接点(Join point)增删改查的方法都可以被增强,这些方法被称为连接点
切入点(Pointcut)匹配连接点的断言,在AOP中通知和一个切入点变大时关联
通知(Advice)切面对于某个连接点产生的动作
目标(Target)被增强的对象
代理(Proxy)
切面(Aspect)多个通知和切入点的组合
六·通知的类型
前置通知<aop:before>
在某个连接点执行之前通知,可以获取切入点的信息
后置通知<aop:after-returning>
在某个连接点退出的时候执行的通知,可以获取方法的返回值
环绕通知<aop:around>
在某个连接点执行前后进行两次通知,可以阻止方法的执行
异常抛出通知<aop:after-throwing>
在被增强的方法发送异常的时候执行,可以获取异常的信息
最终通知<aop:after>
无论代码是否异常都会执行
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here --> <!-- 配置目标对象 --> <bean id="productDao" class="com.itcase.spring.day02.demo3.ProductDaoImpl"></bean> <!-- 把切面类交给Spring管理 --> <bean id="myAspectj" class="com.itcase.spring.day02.demo3.MyAspectJXML"></bean> <!-- 通过AOP的配置完成对目标类产生代理 --> <aop:config> <!-- 表达式配置哪些类的哪些方法需要进行增强 --> <!-- *是任意返回值类型 ..是指任意参数 --> <aop:pointcut expression="execution(* com.itcase.spring.day02.demo3.ProductDaoImpl.save(..))" id="pointcut1"/> <aop:pointcut expression="execution(* com.itcase.spring.day02.demo3.ProductDaoImpl.delete(..))" id="pointcut2"/> <aop:pointcut expression="execution(* com.itcase.spring.day02.demo3.ProductDaoImpl.update(..))" id="pointcut3"/> <aop:pointcut expression="execution(* com.itcase.spring.day02.demo3.ProductDaoImpl.find(..))" id="pointcut4"/> <!-- 配置切面 --> <aop:aspect ref="myAspectj"> <!-- 前置通知 --> <aop:before method="checkPri" pointcut-ref="pointcut1"/> <!--后置通知 --> <aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result"/> <!-- 环绕通知 --> <aop:around method="around" pointcut-ref="pointcut3"/> <!-- 异常抛出通知 --> <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/> <!-- 最终通知 --> <aop:after method="after" pointcut-ref="pointcut4"/> </aop:aspect> </aop:config> </beans>
七·Spring常用的注入方式
1.构造器的依赖注入
public class Employee2 { private String name; private Car car; public Employee2(String name, Car car) { super(); this.name = name; this.car = car; } @Override public String toString() { return "Employee [name=" + name + ", car=" + car + "]"; } }
xml配置
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="employee2" class="com.itcase.spring.day01.demo4.Employee2"> <constructor-arg name="name" value="usibian"></constructor-arg> <constructor-arg name="car" ref="car"></constructor-arg> </bean> </beans>
2.Setter方法注入
public class Employee { private String name; private Car2 car2; @Override public String toString() { return "Employee [name=" + name + ", car2=" + car2 + "]"; } public void setName(String name) { this.name = name; } public void setCar2(Car2 car2) { this.car2 = car2; } }
xml配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- value只能是普通属性的值,如果是属性是其他类的话使用ref关联其他的bean配置 --> <bean id="employee" class="com.itcase.spring.day01.demo4.Employee"> <property name="name" value="wnagwu"></property> <property name="car2" ref="car2"></property> </bean> </beans>
3.基于注解的注入
@Component("person") //适用于所有层
@Service("person") //适用于Service层
@Repository("person") //适用于持久层
@Controller("person") //适用于Controller层
八·ApplicationContext通常的实现
ClasspathXmlApplicationContext;加载类路径下的配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
FileSystemXmlApplicationContext:加载文件系统下的配置文件