Spring知识体系大全(IOC,AOP,JDBC,事务)

一、准备工作

1.创建Maven的java项目。

2.导入java项目的依赖

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.3.10.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.10.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.3.10.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.2</version>
    </dependency>
</dependencies>

3.编写applicationContext.xml 文件

src->main->resources->applicationContext.xml

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

二、使用spring创建bean对象

不需要再手动new对象

1.向applicationContext.xml配置文件中加入bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">
    <bean id="stu" class="demo.bean.Student">
        <property name="name" value="小明"></property>
        <property name="age" value="18"></property>
    </bean>
</beans>

2.通过spring的方式获取对象,只能通过空参构造创建

@Test
    public void test2(){  // 通过spring的方式获取对象,调用方法

        //1 加载spring的配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

        //2 通过spring的方式获取对象
        Student stu = ac.getBean("stu",Student.class);
        /*
        * stu对象是通过ac的getBean方式获取到的。那么这个stu对象就是由spring框架负责创建的
        *
        * 当spring的配置文件applicationContext.xml文件加载后。spring读取 <bean id="" class>的配置
        *  spring就会根据 class中配置的类全名,反射方式创建对象,在读取<property>中的内容完成赋值
        *
        * 把创建好的对象放到一个容器(类似于map)中储存起来 -------> key:配置时的id  value就是spring创建的对象
        *
        * ac.getBean(配置时的id值) 就获取到的容器中储存对象。
        * */
        System.out.println(stu.getId()+"\t"+stu.getName()+"\t"+stu.getAge());
        stu.sayHello();

    }

3.spring创建对象是否单例

默认是单例,也可更改,加上scope属性
在这里插入图片描述

三、SpringIOC 讲解

IOC控制反转

* IOC Inversion of Control 控制反转。
*
*     控制反转就是只对象控制权的反转。
*     在没有使用IOC之前,对象的创建都是由应用程序来负责的(程序员在代码中自己new)
*     在使用了Spring(spring的IOC)后,对象的创建交给了spring(对象由spring负责创建)
*     这种对象的控制器由应用程序转到spring的现象就叫做控制反转。

DI依赖注入

依赖注入(Dependency Injection)

   * 类与类的关系:
   *
   *     1 继承关系   class A extends B
   *     2 关联关系
   *                 class A{
   *                 }
   *
   *                 class B{
   *                   private  A a;
   *                 }
   *
   *                 B类中的成员变量是A类型。  A类和B类是关联关系
   *
   *     3 依赖关系
   *
   *               Class C{
   *
   *               }
   *
   *               class D{
   *                           public void fun(C c){
   *                           }
   *                }
   *
   *               D类中的方法使用C类型。D类和C类就是依赖关系。D依赖C
   *
  •   要讲解的Spring中依赖注入的依赖是广义上的依赖。 只要A类中使用了B类,就说A类依赖B类型
    
  •    依赖注入:   不使用spring之前,依赖的对象也是由应用程序来控制(自己new)
    
  •                使用spring之后,依赖的对象靠spring来注入!!!
    

所以,依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,由spring来创建对象,实现对象之间的解耦。

spring的工厂

BeanFactory 和ApplicationContext的区别:
1.ApplicationContext是BeanFactory 的子接口,比BeanFactory 拥有更多功能。
2.创建对象的时机不同:
ApplicationContext是加载完spring的配置文件后,就创建对象。
BeanFactory 是调用getBean时才创建对象。

四、属性注入

set注入

bean中必须有无参构造,属性有set方法

 <bean id="stu" class="demo.bean.Student" >
        <property name="name" value="小明"></property>
        <property name="age" value="18"></property>
    </bean>

构造器注入

bean中必须有有参构造,可以加入get方法获取属性值

<bean id="car" class="demo.bean.Car">
        <constructor-arg name="name" value="宝马"></constructor-arg>
        <constructor-arg name="color" value="red"></constructor-arg>
    </bean>

复杂类型注入,属于set注入

 	private String[] arr;
    private List list;
    private Set set;
    private Map map;
    private Properties prop;
 <bean id="array" class="demo.bean.Array">
		<!--数组-->
        <property name="arr">
            <array>
                <value>arr1</value>
                <value>arr2</value>
                <value>arr3</value>
            </array>
        </property>
        <!--list集合-->
        <property name="list">
            <list>
                <value>list1</value>
                <value>list2</value>
                <value>list3</value>
            </list>
        </property>
        <!--set集合-->
        <property name="set">
            <set>
                <value>set1</value>
                <value>set2</value>
                <value>set3</value>
            </set>
        </property>
        <!--map集合-->
        <property name="map">
            <map>
                <entry key="map1" value="111"></entry>
                <entry key="map2" value="222"></entry>
                <entry key="map3" value="333"></entry>
            </map>
        </property>
        <!--Properties配置文件-->
        <property name="prop">
            <props>
                <prop key="prop1">111</prop>
                <prop key="prop2">222</prop>
                <prop key="prop3">333</prop>
            </props>
        </property>
    </bean>

五、SpringAOP 讲解

面向切面编程Aspect Oriented Programming

AOP名词解释

在这里插入图片描述
目标(Target)
没有增强功能之前的代码(要被增强,要增加新功能)
切面(Aspect)
要增强的新功能(方法),放在切面中
织入(Weaving)
动词,把目标和切面切在一起的动作(把切面切入到目标中)
代理(Proxy)
目标和切面织到一起后形成的新对象(即具有目标的原有功能,有具体增强的新功能)
切入点(PointCut)
目标中所有可以被切面切的地方(一般是目标中的方法)

连接点(JoinPoint)
当切面真的来切这个切入点了,这个切入点就变成了连接点

通知(Advice)
告诉切面在哪里(在目标方法调用之前、目标方法调用之后、环绕、抛异常时)去切

添加依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.3.10.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>4.3.10.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.6.12</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.6.12</version>
</dependency>
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.1_3</version>
</dependency>

创建切面类

public class Aop {
    public void method(){
        System.out.println("切面。。。。。。");
    }
}

配置切入

 <bean id="aop" class="demo.aspect.Aop"></bean>
    <!--配置切入-->
    <aop:config>
        <!--切入点-->
        <aop:pointcut id="allservice" expression="execution(* demo.service.StudentServiceImpl.*(..))"/>
        <!--切面-->
        <aop:aspect ref="aop">
            <aop:before method="method" pointcut-ref="allservice"></aop:before>
        </aop:aspect>
    </aop:config>

方法命名add*(…):所有以add开头的方法
在这里插入图片描述

效果

在这里插入图片描述

通知说明

在这里插入图片描述
Around通知较为特殊,需要在切面方法中放行目标方法 pjp.proceed();

<aop:around method="myAround" pointcut-ref="allServiceMethod"/>

放行目标方法

public void myAround(ProceedingJoinPoint pjp){
		
		System.out.println("around 环绕 ,在目标方式之前执行###");
		
		try {
			pjp.proceed();
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} // 调用目标方法
		
		System.out.println("around 环绕 ,在目标方式之后执行####");
	}

获取连接点

public class Aop {
    public void method(JoinPoint jp){
		
		jp.getArgs();  // 获取被切的切入点(方法)的参数
		String name = jp.getSignature().getName(); //获取被切的切入点(方法)的名字
}

六、spring整合JDBC

1.添加依赖

除了通用的IOC依赖,还有以下依赖

  <!-- druid mysql-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.45</version>
    </dependency>
    <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

   <!-- spring-jdbc  spring-tx -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.3.10.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>4.3.10.RELEASE</version>
    </dependency>

2.书写dao

public class AddUserImpl implements AddUser{
    JdbcTemplate jt;

    public JdbcTemplate getJt() {
        return jt;
    }

    public void setJt(JdbcTemplate jt) {
        this.jt = jt;
    }

    @Override
    public int add(User user) {
        String sql="insert into users values(null,?,?);";
        int update = jt.update(sql, user.getUsername(), user.getPassword());
        return update;
    }
}

3.书写配置文件

   <!--配置持久层操作对象-->
    <bean id="jdbctemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="ds"></property>
    </bean>
    <!--配置持久层-->
    <bean id="userdao" class="demo.dao.AddUserImpl">
        <property name="jt" ref="jdbctemplate"></property>
    </bean>
    <!--配置数据源-->
    <bean id="ds" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="jdbc:mysql:///test"></property>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>

七、spring注解方式IOC开发

1.添加配置文件

 <!--开启spring注解方式-->
    <context:annotation-config></context:annotation-config>
    <!--设置扫描路径-->
    <!--spring会为扫描路径下所有添加了@Component注解的类创建spring的bean-->
    <context:component-scan base-package="demo"></context:component-scan>
    <!--开启AOP注解-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

2.类上添加注解

@Component//bean的id默认是类名首字母小写
//@Component("aa")
@Scope("prototype")
public class Transaction {
    @Autowired//自动装配,把类型匹配的bean注入

    private Car c;
    @Autowired
    private Ship s;

    public Car getC() {
        return c;
    }

    public void setC(Car c) {
        this.c = c;
    }

    public Ship getS() {
        return s;
    }

    public void setS(Ship s) {
        this.s = s;
    }
}

3.常用注解

  • @Component :添加了这个注解的类会被spring扫描当成 bean来处理
    可以设置bean的id : @Component(“起名字bean的id”)
    也可以不设置bean的id 默认就是类名首字母变小写

  • @Autowired : 自动装配(按类型)
    问题:当多个类型符合时,将无法注入

解决:
在这里插入图片描述

在这里插入图片描述

  • @Scope(“prototype”) 更改单例为每次getBean创建新的对象

  • Spring还提供了以下几个注解来替代 @Component
    @Controller 一般加在控制层
    @Service 一般加在业务层
    @Repository 一般加在持久层
    作用和@Component完全相同(可能会在以后的版本中有不同)

八、注解方式AOP开发

1.添加配置文件

<!-- 开启注解方式的aop -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

2.配置切面注解

@Component
@Aspect//指定切面
public class log {
    //方法一
    @Pointcut("execution(* demo.service.*.*(..))")
    public void anyMethod(){//写一个随意的方法,目的引入切入点

    }
    //方法二
    @Before("execution(* demo.service.*.*(..))")//直接指定切入点
    public void before(){
        System.out.println("before............");
    }
    @After("execution(* demo.service.*.*(..))")
    public void after(){
        System.out.println("after............");
    }
    @AfterReturning("anyMethod()")//使用上面的方法名指定切入点
    public void afterReturn(){
        System.out.println("afterReturning............");
    }
    @Around("execution(* demo.service.*.*(..))")
    public void around(ProceedingJoinPoint jp){
        System.out.println("around 1----------");
        try {
            jp.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("around 2------------");
    }

}

3.切面注解的两种方式对比

方式一固定,一旦修改就都改变。
方式二较为灵活。

九、修改ApplicationContext对象

1.添加依赖

在这里插入图片描述

2.设置监听器

监听器ContextLoaderListener的init方法,随着服务器启动,servletContext的创建而执行,让servletContext加载context-param中的参数,加载xml,生成了ApplicationContext对象。
在这里插入图片描述

3.获取applicationContext对象

避免每次都new,一直使用servletContext中的ApplicationContext
在这里插入图片描述

十、spring事务

1.配置文件方式事务开发

配置事务管理器和切入点

<bean id="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource"></bean>


    <!-- 配置事务管理器(切面)   目标就是service-->
    <!-- spring针对不同的持久层提供了不同的事务管理器(切面)  jdbc:DataSourceTransactionManager-->
    <!-- 事务管理器可以控制事务的提交和回滚 需要操作数据库  需要把dataSource注入给事务管理器-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="ds"></property>
    </bean>

    <!-- 定义事务的传播规则-->
    <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
        <tx:attributes>
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="modify*" propagation="REQUIRED"/>
            <tx:method name="remove*" propagation="REQUIRED"/>
            <tx:method name="zhuanzhang" propagation="REQUIRED" no-rollback-for="java.lang.ArithmeticException" />
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="allServiceMethods" expression="execution(* com.offcn.service.impl.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="allServiceMethods"></aop:advisor>
    </aop:config>

2.事务的传播规则

在这里插入图片描述

3.回滚规则

默认情况下spring的事务管理是碰见异常就回滚
no-rollback-for:碰见这种异常不回滚,其他异常都回滚

4.注解方式事务开发

1.配置事务管理器,开启注解方式事务

<bean id="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource"></bean>


    <!-- 注解方式的事务管理,事务管理器还是需要配置-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="ds"></property>
    </bean>
    <!--引入事务管理器-->
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager" proxy-target-class="true"></tx:annotation-driven>

2.代码
使用@Transactional注解: 可以加在类上,也可以加在方法

                  加在类上,这个类中的所有public修饰的方法都会被事务管理
                  加在方法上,就是这个具体的方法会被事务管理
@Service("accountService")
//@Transactional(propagation = Propagation.REQUIRED) // 这种配置,对类中的每个方法都起作用
public class AccountServiceImpl implements AccountService {
@Transactional(propagation = Propagation.REQUIRED)  // 加在方法上,只对当前方法起作用
public String zhuanzhang(int outId, int inId, int money) {

5.配置文件方式和注解方式比较

  • 配置文件方式可以一次对指定的所有切入点添加事务。
  • 注解方式需要挨个在每个类上添加,如果类多的情况下,显然麻烦。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值