Spring学习笔记

导读:本篇文章讲解 Spring学习笔记,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

1 Spring配置文件

1.1 详解

Bean标签基本配置 用于配置对象交由Spring创建。默认情况调用的是类中的无参构造函数(若没有无参构造函数则不能创建成功)

id:容器中的唯一标识
class:Bean的全限定名

范围配置

scope:指对象的作用范围,取值如下

在这里插入图片描述 取值为singleton时,userDao地址相同,表示为一个唯一的userDao Bean的创建时机为加载xml文件时

生命周期:
对象创建:当应用加载,创建容器时,对象创建
对象运行:容器在,对象一直存活
对象销毁:销毁容器时,对象销毁

在这里插入图片描述取值为prototype时,userDao地址不相同,表示为两个的userDao Bean的创建时机为getBean时

生命周期:
对象创建:使用对象时,创建实例
对象运行:对象在使用中,则一直存活
对象销毁:当长时间没有强引用指向该对象,被垃圾回收器回收

在这里插入图片描述

生命周期配置

init-method:指定类中的初始化方法名
destroy-method:指定类中销毁方法名

在这里插入图片描述 在这里插入图片描述

Bean实例化三种方式

1、无参构造

如上各小节展示,通过无参构造方法实例化 在这里插入图片描述

2、工厂静态

先创建静态工厂 在这里插入图片描述 再修改配置,class属性改为静态工厂类,为factory-method属性添加静态方法 在这里插入图片描述

3、工厂实例 在这里插入图片描述 配置通过两个Bean完成,先配置工厂的Bean,再通过factory-bean、factory-method俩属性使用工厂的bean 在这里插入图片描述

1.2 依赖注入

依赖注入(Dependency Injection):Spring框架核心IOC的具体实现

在Spring容器中将UserDao设置在UserService内部 在这里插入图片描述 Bean依赖注入方式

1、构造方法

在这里插入图片描述 配置中的name值对应有参构造的参数 在这里插入图片描述

2、set方法

形式一:

UserService对应代码 在这里插入图片描述 xml文件里配置 在这里插入图片描述 ————————————————-分割线——————————————————-

!!!!如果通过new的形式创建UserService对象,在调用save方法时会出现空指针异常 在这里插入图片描述 原因在于UserServiceImpl类中的UserDao没有赋值,通过new的形式,不是从IOC容器中取值,即UserDao没注入 在这里插入图片描述

形式二:

仅需修改配置文件 1、引入命名空间

xmlns:p="http://www.springframework.org/schema/p"

2、修改注入方式

<bean id="userService" class="wsw.Service.Impl.UserServiceImpl" p:userDao-ref="userDao"/>

Bean依赖注入的数据类型

1 普通数据类型、2 集合数据类型、3 引用数据类型

1、普通数据类型 在这里插入图片描述 配置文件 :property属性里 对象引用ref 普通数据用value

<bean id="userDao" class="wsw.Dao.Impl.UserDaoImpl" >
        <property name="a" value="李云龙"/> 
        <property name="b" value="48"/>
    </bean>

2、集合数据类型 在这里插入图片描述 配置文件: 其中user1、user2的bean 在map中使用

<bean id="userDao" class="wsw.Dao.Impl.UserDaoImpl">
        <property name="strlist">
            <list>
                <value>a</value>
                <value>b</value>
                <value>c</value>
            </list>
        </property>
        <property name="maps">
            <map>
                <entry key="u1" value-ref="user1"/>
                <entry key="u2" value-ref="user2"/>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="1">1</prop>
                <prop key="2">2</prop>
                <prop key="3">3</prop>
            </props>
        </property>
    </bean>
<bean id="user1" class="wsw.Domain.User">
        <property name="username" value="大大怪将军"/>
        <property name="addr" value="地球"/>
    </bean>
    <bean id="user2" class="wsw.Domain.User">
        <property name="username" value="小小怪下士"/>
        <property name="addr" value="地球"/>
    </bean>

1.3 分模块开发

引入其他配置文件

<import resource="applicationContext-xxx.xml"/>

2 Spring相关API

ApplicationContext实现类:

1、ClassPathXmlApplicationContext(推荐使用) 从类的根路径下加载配置文件

2、FileSystemXmlApplicationContext 从磁盘路径加载配置文件,配置文件可在磁盘的任意位置(使用绝对路径)

3、AnnotationConfigApplicationContext 使用注解配置容器对象时,需使用此类来创建spring容器,以此来读取注解。

getBean()方法使用 在这里插入图片描述 在这里插入图片描述 当存在多个同一类型的,只能使用方式一 id的形式 !!!!!!

3 Spring配置数据源

数据源,即连接池,为提高程序性能

先实例化数据源,初始化部分连接资源;使用连接资源时从数据源中获取;使用完毕后将连接资源归还给数据源。

常见数据源:DBCP、C3P0、BoneCP、Druid等

3.1 数据源开发步骤

1 导入数据源的坐标 和 数据库驱动坐标

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.32</version>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

2 创建数据源对象 3 设置数据源的基本连接数据

//测试手动创建Druid数据源
    @Test
    public void test1() throws Exception {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/ssm");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        DruidPooledConnection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();

    }
    //测试手动创建c3p0数据源
    @Test
    public void test2() throws Exception {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm");
        dataSource.setUser("root");
        dataSource.setPassword("123456");
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();

    }

4 使用数据源获取连接资源 和 归还连接资源

——————————————————-分割————————————————— 为解耦合,需抽取jdbc.properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.username=root
jdbc.password=123456

通过ResourceBundle的getBundle方法获取文件名,进而获取各参数,重复上述配置

	//测试手动创建c3p0数据源(加载配置文件)
    @Test
    public void test3() throws Exception {
        //读取配置文件
        ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
        String driver = bundle.getString("jdbc.driver");
        String url = bundle.getString("jdbc.url");
        String username = bundle.getString("jdbc.username");
        String password = bundle.getString("jdbc.password");

        //创建数据源对象,设置连接参数
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }

3.2 spring配置数据源

DataSource由Spring容器进行创建 xml文件配置Bean

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ssm"/>
        <property name="user" value="root"/>
        <property name="password" value="123456"/>
    </bean>

property的name 对应的是类的set方法名

测试方法:

//测试Spring容器创建c3p0数据源对象
    @Test
    public void test4() throws Exception {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        DataSource dataSource = (DataSource) applicationContext.getBean("dataSource");
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }

3.3 spring加载properties文件

命名空间添加:

xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"

随后配置

<!--加载外部properties文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
   
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

4 Spring注解开发

4.1 注解开发

原始注解:

	* @Component:使用在类上 用于实例化Bean
	* @Controller:使用在web层类上 用于实例化Bean
	* @Service:使用在service层类上 用于实例化Bean
	* @Repository:使用在dao层类上 用于实例化Bean
	* @Autowired:使用在字段上 用于根据类型依赖注入
	* @Qualifier:结合@Autowired一起使用 用于根据名称进行依赖注入
	* @Resource:相当于@Autowired+@Qualifier,按照名称进行注入
			@Resource(name="xxx")
	* @Value:注入普通属性
	* @Scope:标注Bean的作用范围  singleton单例 prototype多例
	@PostConstruct:使用在方法上 标注该方法是Bean的初始化方法
	@PreDestroy:使用在方法上 标注该方法是Bean的销毁方法

其中Controller、Service、Repository 与Component效果相同,只是在不同层上用(区分使用)

使用注解开发,需在applicationContext.xml中配置组件扫描。 作用:指定哪个包及其子包下的Bean需进行扫描,以识别使用注解配置的类、字段和方法。

<context:component-scan base-package="xxx"></context:component-scan>

新注解:

	@Configuration:用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解
	@ComponentScan:用于指定Spring在初始化容器时要扫描的包
	@Bean:使用在方法上,标注将该方法的返回值以指定名称存储在Spring容器中
	@PropertySource:用于加载.properties文件中的配置
	@Import:用于导入其他配置类

创建两个配置类 SpringConfiguration类为核心类

@Configuration //标志该类为核心配置类
@ComponentScan("wsw")//<context:component-scan base-package="wsw"/>
@Import(DataSourceConfiguration.class) //<import resource=""/>
public class SpringConfiguration {
}

DataSourceConfiguration类为连接数据库类

@PropertySource("classpath:jdbc.properties")//<context:property-placeholder location="classpath:jdbc.properties"/>
public class DataSourceConfiguration {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean("dataSource")
    public DataSource getDataSource() throws Exception{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

5 Spring集成Junit

步骤: 1 导入spring集成Junit坐标 在这里插入图片描述

2 使用@Runwith注解替换原来的运行期

3 使用@ContextConfiguration指定配置文件或配置类

4 使用@Autowired注入需要测试的对象

5 创建测试方法进行测试 在这里插入图片描述

6 Spring AOP

Aspect Oriented Programming。面向切面编程 通过预编译方式 和 运行期动态代理实现程序功能的统一维护的一种技术

作用:

程序运行期间,在不修改源码的情况下对方法进行功能增强

优势:

减少重复代码,提高开发效率,便于维护

常用术语: · Target(目标对象):代理的目标对象 · Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类 · Joinpoint(连接点):即目标对象的方法 · Pointcut(切入点):即要进行增强的目标对象方法 · Advice(通知/增强):增强方法 · Aspect(切面):即增强方法与要被增强的目标方法结合 · Weaving(织入):指切面的过程

编写步骤

· 编写核心业务代码(目标类的目标方法)
· 编写切面类,切面类中有通知(增强方法)
· 在配置文件中,配置织入关系,即将哪些通知与连接点结合

6.1 Spring的AOP

动态代理技术

1 JDK代理:基于接口的动态代理,运行期间基于接口动态地生成代理对象 2 cglib代理:基于父类的动态代理,动态生成子对象

在这里插入图片描述 cglib的代理对象是目标对象的子类,而jdk代理对象和目标对象都实现了目标接口,jdk的代理对象还继承了Proxy

基于JDK的动态代理 增强函数advice

public class Advice {

    public void before(){
        System.out.println("前置增强.");
    }

    public void after(){
        System.out.println("后置增强.");
    }

}

目标对象方法target

public class Target implements TargetInterface {
    @Override
    public void save() {
        System.out.println("save running............");
    }
}

代理对象方法proxytest

public class ProxyTest {
    public static void main(String[] args) {
        //创建目标对象
        final Target target = new Target();

        //获得增强对象
        final Advice advice = new Advice();
		
		//返回值为动态生成的代理对象
        TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),//目标对象类加载器
                target.getClass().getInterfaces(),//目标对象 相同的接口字节码对象数组
                new InvocationHandler() {
                    //调用代理对象的任何方法,其实质是执行的均是invoke方法
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //前置增强
                        advice.before();
                        Object invoke = method.invoke(target, args);//执行目标方法
                        //后置增强
                        advice.after();
                        return invoke;
                    }
                }
        );
        proxy.save();
    }
}

cglib动态代理 在这里插入图片描述

proxytest

public class ProxyTest {
    public static void main(String[] args) {
        //创建目标对象
        final Target target = new Target();

        //获得增强对象
        final Advice advice = new Advice();

        //返回值为动态生成的代理对象 基于cglib
        //1 创建增强器
        Enhancer enhancer = new Enhancer();
        //2 设置父类(目标)
        enhancer.setSuperclass(Target.class);
        //3 设置回调
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                //前置
                advice.before();
                Object invoke = method.invoke(target, args);//执行目标方法
                //后置
                advice.after();
                return invoke;
            }
        });
        //4 创建代理对象
        Target proxy = (Target) enhancer.create();

        proxy.save();
    }

}

6.2 基于XML的AOP开发

步骤: 1 导入AOP相关坐标

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.12</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.4</version>
    </dependency>

2 创建目标接口 、目标类(内部有切点) 在这里插入图片描述

3 创建切面类(内部有增强方法) 在这里插入图片描述

4 将目标类、切面类的对象创建权交给spring 在这里插入图片描述

5 在applicationContext.xml中配置织入关系 头部信息

xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"

在这里插入图片描述

6 测试代码 在这里插入图片描述

切点表达式 语法:

execution([修饰符] 返回值类型 包名.类名.方法名(参数))

·访问修饰符可省略 ·返回值类型、包名、类名、方法名可使用星号*代表任意 ·包名与类名之间一个点.代表当前包下的类,两个点…表示当前包及其子包下的类 ·参数列表可使用两个点…表任意个数、任意类型的参数列表

通知 语法:

<aop:通知类型 method= "切面类中方法名"  pointcut= "切点表达式 " />

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

切点表达式抽取 使用pointcut-ref属性代替pointcut属性来引用抽取后的切点表达式 在这里插入图片描述

6.3 基于注解的AOP开发

步骤: 1 创建目标接口、目标类 2 创建切面类 3 将目标类和切面类的对象创建权交给spring 在这里插入图片描述 在这里插入图片描述

4 在切面类中使用注解配置织入关系 在这里插入图片描述

5 在配置文件中开启组件扫描和AOP的自动代理 需要引入头部信息

xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd">

配置文件中代码

<!--开启组件扫描-->
    <context:component-scan base-package="wsw.AOP" />

    <!--AOP自动代理-->
    <aop:aspectj-autoproxy/>

6 测试

通知类型 @通知注解(“切点表达式”) 在这里插入图片描述

切点表达式抽取 在这里插入图片描述

7 Spring 事物控制

7.1 编程式事务控制相关对象

1 PlatformTransactionManager 在这里插入图片描述 在这里插入图片描述

2 TransactionDefinition 在这里插入图片描述 2.1 事务隔离级别 设置隔离级别,可解决事务并发产生的问题,如脏读、不可重复读、虚读

· ISOLATION_DEFAULT
· ISOLATION_READ_UNCOMMITTED
· ISOLATION_READ_COMMITTED  可解决脏读
· ISOLATION_REPEATABLE_READ  可解决 不可重复读
· ISOLATION_SERIALIZABLE  全都能解决,但性能低,相当于锁表

2.2 事务传播行为 主要作用:解决 业务方法在调用业务方法时,它们之间事务统一性的问题 在这里插入图片描述

3 TransactionStatus

事务状态 事务具体的运行状态 在这里插入图片描述 平台对象操作事务行为,定义对象设置事务属性,状态对象反馈事务运行过程中的信息

7.2 基于XML的声明式事务控制

采用声明的方式来处理事务,即在配置文件中进行声明 Spring声明式事务控制底层即为AOP

需明确:

1 谁是切点?
2 谁是通知?
3 配置切面?

在这里插入图片描述 通过事务控制,是该方法内的accountDao的out和in方法执行统一,即不会发生 一个执行 另一个未执行

pom.xml配置

 <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.32</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

切点配置 在这里插入图片描述 平台事务管理器配置(如果Dao层的实现不是原生的JDBC,则配置需要更改) 在这里插入图片描述 通知事务增强配置 在这里插入图片描述< tx:attributes >是用来设置事务的属性信息 < tx:method >代表切点方法的事务参数的配置

name:切点方法名称
isolation:事务的隔离级别
propogation:事务的传播行为
timeout:超时时间
read-only:是否只读

AOP织入配置 在这里插入图片描述

7.3 基于注解的声明式事务控制

自定义的Bean用注解,非自定义的Bean需要添加到xml配置文件中

开启组件扫描 添加头部信息 在这里插入图片描述在这里插入图片描述

切点增强 在方法上加 @Transactional( ) 在这里插入图片描述 如果注解使用在类上,则该类下的所有方法均使用同一套注解参数配置,如果方法、类上均存在注解,则就近原则生效

还需配置事务注解驱动 在这里插入图片描述 在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/2626.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!