1、Spring
- 一款轻量级的控制反转(IoC)和面向切面(AOP)的框架
2、IoC
- 控制反转:讲对象的创建,管理,转配交给IoC容器
- 实现方式:依赖注入(提供set方法)
@Test
public void shouldAnswerWithTrue() {
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
User user = (User) context.getBean("user");
System.out.println(user);
}
IoC创建对象的方式
- 基于类型创建(最不建议使用)
<bean id="user" class="com.mojo.pojo.User">
<property name="name" value="mojo"></property>
<property name="age" value="11"></property>
<constructor-arg type="java.lang.String" value="mojo"/>
</bean>
<!--User{name='mojo', age=0}-->
- 基于下标创建
<bean id="user" class="com.mojo.pojo.User">
<constructor-arg index="0" value="mojo"/>
</bean>
- 基于构造器参数名创建
<bean id="user" class="com.mojo.pojo.User">
<constructor-arg name="age" value="11"/>
</bean>
3、Spring配置
3.1、import导入
作用:将多个xml合并为一个xml,对应注解@Import的功能
4、依赖注入
4.1、构造器注入:参考目录2
4.2、set方法注入(部分xml)
<property name="age" value="11"/>
<property name="name" value="mojo"/>
<property name="hobby" >
<list>
<value>篮球</value>
<value>足球</value>
<value>电影</value>
</list>
</property>
4.3、 扩展注入
4.3.1、p-namespace:
4.3.2、c-namespace:
p和c分别是property和constructor的简称,这两种扩展注入可以理解为是一种语法糖,减少了代码量。同时,这两种扩展注入需要引入 XSD schema。
5、自动装配
// TODO
6、注解开发
7、代理模式
代理模式是spring的AOP的核心实现模式
7.1、静态代理
代理模式中可以分为四个角色:
-
抽象角色:接口或抽象类,里面有核心的业务
/** * 租房-代理模式中的抽象角色 * * @author <a href="mailto:mojo_jj@163.com">Mojo</a> * */ public interface Rent { //核心操作 void rent(); }
-
真实角色:被代理的角色
/**
* 房东-代理模式中的真实角色
*
* @author <a href="mailto:mojo_jj@163.com">Mojo</a>
*/
public class Landlord implements Rent {
@Override
public void rent() {
System.out.println("房东要出租房屋!");
}
}
- 代理角色:代理上面的真实角色,同时可以做一些附属操作
/**
* 中介-代理模式中的代理角色
*
* @author <a href="mailto:mojo_jj@163.com">Mojo</a>
*/
public class Proxy implements Rent {
private Landlord landlord;
public Proxy(Landlord landlord) {
this.landlord = landlord;
}
@Override
public void rent() {
landlord.rent();
contract();
}
//代理角色可做一些附属操作
public void contract() {
System.out.println("中介帮忙签合同");
}
}
- 客户角色(调用方):
/**
* 客户端-代理模式中的调用方
*
* @author <a href="mailto:mojo_jj@163.com">Mojo</a>
*/
public class Client {
public static void main(String[] args) {
Landlord landlord = new Landlord();
Proxy proxy = new Proxy(landlord);
proxy.rent();
}
}
优点:
缺点:一个真实角色就会产生一个代理角色,代码量成倍增加
7.2、动态代理
动态代理分类:
1、基于jdk的动态代理
public class ProxyInvocationHandler implements InvocationHandler {
//真实角色
private Object t;
public void setT(Object t) {
this.t = t;
}
//生成获取代理类(代理角色)
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
//获取真实角色的接口数组
t.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
log(name);
return method.invoke(t, args);
}
public void log(String msg) {
System.out.println("使用" + msg + "方法");
}
}
调用
public class Client {
public static void main(String[] args) {
//真实角色
Rent landlord = new Landlord();
ProxyInvocationHandler invocationHandler = new ProxyInvocationHandler();
invocationHandler.setT(landlord);
//获取代理角色,基于jdk的动态代理必须用接口来接受
Rent proxy = (Rent) invocationHandler.getProxy();
proxy.rent();
}
}
8、AOP
8.1、实现方式一:原生spring api方式
public class Log implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(method.getName() + "方法执行前日志");
}
}
public class AfterLog implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行了" + method.getName() + "方法,方法返回类型为" + method.getReturnType() + ",返回" + returnValue);
}
}
<!-- aop实现第一种方式 spring原声api方式 -->
<aop:config>
<!--切入点 表达式 * * * * *-->
<aop:pointcut id="pointcut" expression="execution(* com.mojo.UserServiceImpl.*(..))"/>
<!--执行环绕增加 aop:pointcut可以直接卸载aop:advisor里面-->
<aop:advisor pointcut-ref="pointcut" advice-ref="log"/>
<aop:advisor pointcut-ref="pointcut" advice-ref="afterLog"/>
</aop:config>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-26Ni6sDG-1619272498173)(C:\Users\masqu\AppData\Roaming\Typora\typora-user-images\image-20210423002338014.png)]
8.2
9、声明式事务和编程式事务
<aop:config>
<!--执行环绕增加 aop:pointcut可以直接卸载aop:advisor里面-->
<aop:advisor pointcut-ref="pointcut" advice-ref="log"/>
<aop:advisor pointcut-ref="pointcut" advice-ref="afterLog"/>
</aop:config>