0
点赞
收藏
分享

微信扫一扫

Spring总结与感悟

Spring重点总结

依赖注入(DI)

set方式注入【重点】

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="address" class="pojo.Address">
<property name="address" value="address你好" />
</bean>

<bean id="student" class="pojo.Student">
<!--第一种,普通值注入 -->
<property name="name" value="name你好" />
<!--第二种,ref注入 -->
<property name="address" ref="address" />

<!--数组注入 -->
<property name="books">
<array>
<value>三国</value>
<value>西游</value>
<value>水浒</value>
</array>
</property>

<!--list列表注入 -->
<property name="hobbies">
<list>
<value>唱</value>
<value>跳</value>
<value>rap</value>
<value>篮球</value>
</list>
</property>

<!--map键值对注入 -->
<property name="card">
<map>
<entry key="username" value="root" />
<entry key="password" value="root" />
</map>
</property>

<!--set(可去重)注入 -->
<property name="game">
<set>
<value>wangzhe</value>
<value>lol</value>
<value>galname</value>
</set>
</property>

<!--空指针null注入 -->
<property name="wife">
<null></null>
</property>

<!--properties常量注入 -->
<property name="infor">
<props>
<prop key="id">20200802</prop>
<prop key="name">cbh</prop>
</props>
</property>
</bean>
</beans>

使用p和c命名空间需要导入xml约束

<!--p命名空间注入/set注入,可以直接注入属性的值-》property-->
<bean id="user" class="pojo.User" p:name="cxk" p:id="20" >
</bean>

<!--c命名空间,通过构造器注入,需要写入有参和无参构造方法-》construct-args-->
<bean id="user2" class="pojo.User" c:name="cbh" c:id="22"></bean>

Bean的自动装配

Spring会在上下文自动寻找,并自动给bean装配属性

在Spring中有三种装配的方式

 

  1. 在xml中显示配置
  2. 在java中显示配置
  3. 隐式的自动装配bean 【重要】

 

  1. byType自动装配:byType会自动查找,和自己对象set方法参数的类型相同的bean
    保证所有的class唯一(类为全局唯一)
  2. byName自动装配:byName会自动查找,和自己对象set对应的值对应的id
    保证所有id唯一,并且和set注入的值一致

实例:

People类

package com.xlf.pojo;

import org.apache.ibatis.annotations.CacheNamespace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import javax.annotation.Resource;

public class People {

@Resource
private Cat cat;
@Resource
// @Qualifier(value = "dog222")
private Dog dog;
private String name;

@Override
public String toString() {
return "People{" +
"cat=" + cat +
", dog=" + dog +
", name='" + name + '\'' +
'}';
}

public Cat getCat() {
return cat;
}

public void setCat(Cat cat) {
this.cat = cat;
}

public Dog getDog() {
return dog;
}

public void setDog(Dog dog) {
this.dog = dog;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

xml配置 -> byType 自动装配

<bean id="cat" class="pojo.Cat"/>
<bean id="dog" class="pojo.Dog"/>

<!--byType会在容器自动查找,和自己对象属性相同的bean
例如,Dog dog; 那么就会查找pojo的Dog类,再进行自动装配
-->
<bean id="people" class="pojo.People" autowire="byType">
<property name="name" value="xlf"></property>
</bean>

xml配置 -> byName 自动装配

<bean id="cat" class="pojo.Cat"/>
<bean id="dog" class="pojo.Dog"/>
<!--byname会在容器自动查找,和自己对象set方法的set后面的值对应的id
例如:setDog(),取set后面的字符作为id,则要id = dog 才可以进行自动装配

-->
<bean id="people" class="pojo.People" autowire="byName">
<property name="name" value="xlf"></property>
</bean>

使用注解实现自动装配

1.导入context约束:xmlns:context="​​http://www.springframework.org/schema/context​​"

2.配置注解的支持:< context:annotation-config/>

@Autowired:默认是byType方式,如果匹配不上,就会byName

public class People {
@Autowired
private Cat cat;
@Autowired
private Dog dog;
private String name;
}

@Resource:默认是byName方式,如果匹配不上,就会byType

public class People {
Resource(name="cat")
private Cat cat;
Resource(name="dog")
private Dog dog;
private String name;
}

@Nullable:字段标记了这个注解,说明该字段可以为空
区别:

@Resource和@Autowired的区别:

  • 都是用来自动装配的,都可以放在属性字段上
  • @Autowired通过byType的方式实现,而且必须要求这个对象存在!【常用】
  • @Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!【常用】
  • 执行顺序不同:@Autowired通过byType的方式实现。@Resource默认通过byname的方式实现

 

 

使用注解开发

使用注解需要导入contex的约束

<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">

<context:annotation-config/>

</beans>

bean

<!--指定要扫描的包,这个包下面的注解才会生效
别只扫一个com.kuang.pojo包-->
<context:component-scan base-package="com.kuang"/>
<context:annotation-config/>

//@Component 组件
//等价于<bean id="user" classs"pojo.User"/>
@Component
public class User {
public String name ="xlf";
}

属性如何注入@value

@Component
public class User {
//相当于<property name="name" value="xlf"/>
@value("xlf")
public String name;

//也可以放在set方法上面
//@value("xlf")
public void setName(String name) {
this.name = name;
}
}

作用域@scope

原型模式prototype,单例模式singleton

 

scope("prototype")相当于<bean scope="prototype"></bean>

AOP

AOP在Spring中的使用

提供声明式事务,允许用户自定义切面

 

  • 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志,安全,缓存,事务等等…
  • 切面(Aspect):横切关注点 被模块化的特殊对象。即,它是一个类。(Log类)
  • 通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。(Log类中的方法)
  • 目标(Target):被通知对象。(生成的代理类)
  • 代理(Proxy):向目标对象应用通知之后创建的对象。(生成的代理类)
  • 切入点(PointCut):切面通知执行的”地点”的定义。(最后两点:在哪个地方执行,比如:method.invoke())
  • 连接点(JointPoint):与切入点匹配的执行点。

 

使用Spring实现AOP

导入jar包

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>

自定义类实现AOP

<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">

<!--注册bean-->
<bean id="userservice" class="service.UserServiceImpl"/>
<bean id="log" class="log.Log"/>
<bean id="afterLog" class="log.AfterLog"/>
<!-- 方式二,自定义 -->
<bean id="diy" class="diy.DiyPointcut"/>
<aop:config>
<!--自定义切面-->
<aop:aspect ref="diy">
<!--切入点-->
<aop:pointcut id="point" expression="execution(* service.UserServiceImpl.*(..))"/>
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>

</beans>

使用注解实现

<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">

<!-- 注册 -->
<bean id="userservice" class="service.UserServiceImpl"/>
<!--方式三,使用注解实现-->
<bean id="diyAnnotation" class="diy.DiyAnnotation"></bean>

<!-- 开启自动代理
实现方式:默认JDK (proxy-targer-class="fasle")
cgbin (proxy-targer-class="true")-->
<aop:aspectj-autoproxy/>

</beans>

  

package diy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect //标注这个类是一个切面
public class DiyAnnotation {

@Before("execution(* service.UserServiceImpl.*(..))")
public void before(){
System.out.println("=====方法执行前=====");
}

@After("execution(* service.UserServiceImpl.*(..))")
public void after(){
System.out.println("=====方法执行后=====");
}

//在环绕增强中,我们可以给地暖管一个参数,代表我们要获取切入的点
@Around("execution(* service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕前");

Object proceed = joinPoint.proceed();

System.out.println("环绕后");
}
}

测试:

public class MyTest5 {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//注意:动态代理代理的是接口
UserService userService = (UserService) context.getBean("userservice");
userService.add();
}
}

输出:

Spring总结与感悟_spring

 

 

声明式事务

事务的ACID原则:1、原子性2、隔离性3、一致性4、持久性

Spring中的事务管理

 

  • 声明式事务:AOP
  • 编程式事务:需要再代码中,进行事务管理

<!--声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="datasource" />
</bean>

<!--结合aop实现事务织入-->
<!--配置事务的通知类-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--给哪些方法配置事务-->
<!--新东西:配置事务的传播特性 propagation-->
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="query" read-only="true"/>
<!-- *号包含上面4个方法:
<tx:method name="*" propagation="REQUIRED"/> -->
</tx:attributes>
</tx:advice>

<!--配置事务切入-->
<aop:config>
<aop:pointcut id="txpointcut" expression="execution(* mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txpointcut"/>
</aop:config>

REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与REQUIRED类似的操作。

声明事务的本质是:当一个事务发生错误时,可以及时的回滚,而不是一部分执行,错误的不执行。

 

感悟

spring的重点三大部分:

 

  • 控制反转(IoC)
  • 面向切面编程(AOP)
  • 事务处理

总结一句话:Spring就是一个轻量级的控制反转(IoC)和面向切面编程(AOP)的框架!

目前,针对一个刚刚入门spring的小白,只是大概地学习了spring,还有很多的不足,接下来要进行spring-mvc的学习,希望在接下来的学习可以更深入的理解spring

 

 

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans        https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="address" class="pojo.Address"><property name="address" value="address你好" /></bean>
<bean id="student" class="pojo.Student"><!--第一种,普通值注入 --><property name="name" value="name你好" /><!--第二种,ref注入 --><property name="address" ref="address" />
<!--数组注入 --><property name="books"><array><value>三国</value><value>西游</value><value>水浒</value></array></property>
<!--list列表注入 --><property name="hobbies"><list><value>唱</value><value>跳</value><value>rap</value><value>篮球</value></list></property>
<!--map键值对注入 --><property name="card"><map><entry key="username" value="root" /><entry key="password" value="root" /></map></property>
<!--set(可去重)注入 --><property name="game"><set><value>wangzhe</value><value>lol</value><value>galname</value></set></property>
<!--空指针null注入 --><property name="wife"><null></null></property>
<!--properties常量注入 --><property name="infor"><props><prop key="id">20200802</prop><prop key="name">cbh</prop></props></property></bean></beans>



举报

相关推荐

0 条评论