什么是spring?
Spring 是轻量级的框架,两大核心:IOC/DI(控制反转/依赖注入)与AOP(面向切面编程)
什么是ioc?
ioc是一种控制反转的思想,也就是说以前面向对象的思想创建一个实例是直接new ,而ioc将控制权交给ioc容器,由ioc容器来完成。这样做的优点能降低耦合性。
Application Context 是 BeanFactory 的子接口,也被成为 Spring 上下文。
常用的ioc容器的实现类
- FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器 XML 文件的完整路径。
- ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器会从 CLASSPATH 中搜索 bean 配置文件。
- WebXmlApplicationContext:该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。
什么是DI?
依赖注入就是通过IOC容器将类之间的关系在容器内部绑定,使得类与类之间进一步解耦,让类更加专注于业务本身而不用处理其他对象的生命周期。无论是IOC或者是DI其实都是为了解耦,前者是为了将类的生命周期交给IOC容器统一管理,后者处理类与类的关系,而这些动作都将在容器内完成。
注入方式:
set方法注入(常用):
构造方法注入(常用)
这是A类
package com.blb.Test;
public class A {
public A() {
System.out.println("A无参构造!");
}
public void say(){
System.out.println("我是A的say");
}
}
这是B类
package com.blb.Test;
public class B {
private A a;
public B(A a) {
System.out.println("B的有参构造");
this.a = a;
}
public B() {
System.out.println("B的无参构造");
}
public A getA() {
System.out.println("B的get");
return a;
}
public void setA(A a) {
System.out.println("B的set.");
this.a = a;
}
}
这是测试类Test :创建一个ioc容器,从ioc容器中获取获取想要的实例
package com.blb.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring.xml");
B b = applicationContext.getBean(B.class);
// A a = applicationContext.getBean(A.class);
}
}
这是spring.xml
<bean id="a" class="com.blb.Test.A" ></bean>
<!-- set方法注入-->
<bean class="com.blb.Test.B" >
<property name="a" ref="a" ></property>
</bean>
<!-- set方法注入(常用)调用B类的set方法 ref属性值和setA()有关,取setA中A的小写-->
<!-- 构造方法注入-->
<bean class="com.blb.Test.B" >
<constructor-arg ref="a"></constructor-arg>
</bean>
<!-- 构造方法注入(常用): 调用B类的有参构造 public B(A a) 与ref属性值有关,与 有参构造的形参相同-->
接口注入(淘汰)
什么是bean?
被ioc容器管理的对象
常用注解:
**@Conponet:**调用构造方法添加到ioc容器中(过程不可控制)
**@bean:**通过返回值添加到ioc容器中(过程可控)
bean作用域:
- singleton
单例模式,在IOC容器中仅存在一个实例 - prototype
多例,每次从IOC容器调用Bean时,都会返回一个新的实例 - request
每次Http请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境 - session
同一个会话共享一个Bean,不同的会话使用不同的Bean,仅适用于WebApplicationContext环境 - application
一般用于portlet应用环境,该作用域仅适用于WebApplicationContext环境
什么是懒加载?
bean初始化的时候不加载调用的时候加载! lazy-init=“true” 该属性为懒加载 默认 false
什么aop?
面向切面的编程。
面向切面组成的部分
切面:即你要切入的模块代码
切入点:模块要切入的地方、要切入的地点
通知:切入模块的运行时机
aop导入的相关jar包
spring-aop、spring-aspects、aspectjweaver
面向切面xml文件配置
<!--面向切面-->
<aop:config>
<!--切面-->
<aop:aspect ref="aop">
<!--切入点-->
<aop:pointcut id="aopPointCut" expression="execution(* com.blb.aop.B.*(..))"/>
<!--通知-->
<!--在什么之前-->
<aop:before method="before" pointcut-ref="aopPointCut"></aop:before>
<!--在什么之后-->
<!--<aop:after method="hellAop" pointcut-ref="aopPointCut"></aop:after>-->
<!--环绕通知-->
<!--<aop:around method="hellAop" pointcut-ref="aopPointCut"></aop:around>-->
<!--异常通知-->
<!--<aop:after-throwing method="hellAop" pointcut-ref="aopPointCut"/>-->
<!--返回通知-->
<!-- <aop:after-returning method="after" pointcut-ref="aopPointCut"/>-->
</aop:aspect>
</aop:config>
面向切面注解使用
package com.blb.aop;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@ComponentScan
@EnableAspectJAutoProxy
public class A {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(A.class);
B b= applicationContext.getBean(B.class);
b.buy();
// ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring.xml");
// B b = applicationContext.getBean(B.class);
// b.buy();
}
}
package com.blb.aop;
import org.springframework.stereotype.Component;
@Component
public class B {
public void buy(){
System.out.println("我买房!");
}
}
package com.blb.aop;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect //指定当前类为切面类
public class C {
@Before("execution(* com.blb.aop.B.buy())")
public void before(){
System.out.println("我贷款100w");
}
@After("execution(* com.blb.aop.B.buy())")
public void after(){
System.out.println("我还款200w");
}
}