Spring基础知识

SpringFramework系统架构

Data Access:数据访问

Data Integration:数据集成

Web:Web开发

Aop:面向切面编程

Aspects:Aop的实现

Core Container:核心容器

Test:单元测试与集成测试

核心概念

IoC/DI

IoC(控制反转):对象的创建控制权转移到外部

DI(依赖注入):在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入

IoC容器

Sprig提供了一个容器,称为IoC容器,用来充当IoC思想的“外部”

Bean

IoC容器负责对象的创建、初始化等一系列工作。被创建或被管理的对象在IoC容器中统称为Bean

IoC入门案例

1、导入Spring文件

2、配置bean标签

id属性给bean起名字,id不能重复

class属性表示bean的定义类型

<bean id="bookDao" class="com.example.dao.Impl.BookDaoImpl"/> <bean id="bookService" class="com.example.service.Impl.BookServiceImpl"/>

3、获取IoC容器

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

4、获取bean

BookDao bookDao = (BookDao)ac.getBean("bookDao");

DI入门案例

5、删除业务层中的new对象

private BookDao bookDao;

6、提供对应的set方法

public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; }

7、配置server与dao的关联

使用property标签

name属性表示配置哪一个具体的属性

ref表示属性参照哪一个bean

<bean id="bookService" class="com.example.service.Impl.BookServiceImpl"> <property name="bookDao" ref="bookDao"></property> </bean>

Bean

Bean配置

1、为bean起别名

使用name属性,多个别名可以使用逗号、空格、分号分隔

<bean id="bookDao" name="bookDao2 bookDao3" class="com.example.dao.Impl.BookDaoImpl"/>

2、bean的作用范围

使用scope属性,默认为singletion单例模式

prototype非单例

<bean id="bookService" class="com.example.service.Impl.BookServiceImpl" scope="singleton">

Bean的实例化

构造方法

配置一个可访问的构造方法(无参构造方法)

无参构造方法如果不存在,将抛出异常BeanCreateionException

public BookDaoImpl() { System.out.println("book dao constructor is running ...."); }

静态工厂

创建一个工厂类,类中创建返回对象的静态方法

使用factory-method属性指定工厂类中的方法

public static OrderDao getOrderDao(){ System.out.println("factory setup...."); return new OrderDaoImpl(); }

<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>

实例工厂

创建一个工厂类

第一个bean指定工厂类、第二个bean指定方法

<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/> <bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>

FactoryBean实现

创建类实现FactoryBean接口

public class UserDaoFactoryBean implements FactoryBean<UserDao> { //代替原始实例工厂中创建对象的方法 public UserDao getObject() throws Exception { return new UserDaoImpl();} public Class<?> getObjectType() { return UserDao.class;} }

Bean的生命周期

生命周期过程

初始化容器:1、创建对象;2、执行构造方法;3、执行属性注入(set);4、执行bean初始化方法

使用bean:执行业务操作

关闭/销毁容器:执行bean销毁方法

配置格式

使用init-method属性和destory-method属性指定方法

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>

接口实现

实现InitializingBean和DisposableBean接口

public class BookServiceImpl implements BookService, InitializingBean, DisposableBean { public void destroy() throws Exception { System.out.println("service destroy"); } public void afterPropertiesSet() throws Exception { System.out.println("service init"); } }

依赖注入

setter注入

引用类型提供set方法

简单类型配置使用property标签value属性注入

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"> <property name="connectionNum" value="100"/> <property name="databaseName" value="mysql"/> </bean>

构造器注入

注入标签换为constructor-arg

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"> <!--根据构造方法参数位置注入--> <constructor-arg index="0" value="mysql"/> <constructor-arg index="1" value="100"/> </bean>

自动装配

使用autowire属性:byType按类型(相同类型的bean唯一)、byName按名称(set方法名称)

只能对引用类型

<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byType"/>

集合注入

对应集合使用对应标签

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"> <!--数组注入--> <property name="array"> <array> <value>100</value> <value>200</value> <value>300</value> </array> </property> <!--list集合注入--> <property name="list"> <list> <value>itcast</value> <value>itheima</value> <value>boxuegu</value> <value>chuanzhihui</value> </list> </property> <!--set集合注入--> <property name="set"> <set> <value>itcast</value> <value>itheima</value> <value>boxuegu</value> <value>boxuegu</value> </set> </property> <!--map集合注入--> <property name="map"> <map> <entry key="country" value="china"/> <entry key="province" value="henan"/> <entry key="city" value="kaifeng"/> </map> </property> <!--Properties注入--> <property name="properties"> <props> <prop key="country">china</prop> <prop key="province">henan</prop> <prop key="city">kaifeng</prop> </props> </property> </bean>

容器

加载配置文件

1、加载类路径下的配置文件

ApplicationContext ctx = new ClassPathXmlApplicationContext("");

2、从文件系统下加载配置文件

ApplicationContext ctx = new FileSystemXmlApplicationContext("");

获取Bean

1、使用名称获取

BookDao bookDao = (BookDao) ctx.getBean("bookDao");

2、使用bean的名称,并指定类型

BookDao bookDao = ctx.getBean("bookDao",BookDao.class);

3、使用bean类型获取(同一类型的bean只能有一个)

BookDao bookDao =ctx.getBean(BookDao.class);

延迟加载

使用lazy-init属性,将值设置为true

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" lazy-init="true"/>

容器总结

BeanFactory是所有容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载

ApplicationContext接口是Spring容器的核心接口,初始化bean时立即加载

ApplicationContext接口常用的实现类

ClassPathXmlApplicationContext

FileSystemXmlApplicationContext

注解开发定义bean

使用@Component定义bean

如果不指定名称,使用根据类型来获取bean

@Component("bookDao") public class BookDaoImpl implements BookDao { }

配置扫面组件加载bean

<context:component-scan base-package="com.itheima"/>

Spring提供了@Component注解的三个衍生注解

@Controller:用于表现层bean定义

@Service:用于业务层bean定义

@Repository:用于数据层bean定义

三者与@Component功能完全相同,只是名称不同

纯注解开发

将配置文件更换为配置类

@Configuration @ComponentScan("com.itheima") public class SpringConfig { }

@Configuration指定为配置类

@ComponentScan指定要扫描的包,如果多个包,添入集合

容器对象获取

ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);

作用范围使用@Scope注解

@Component("bookDao") @Scope("prototype") public class BookDaoImpl implements BookDao { }

生命周期

@PostConstruct

@PostConstruct public void init(){ System.out.println("init"); }

@PreDestory

@PreDestroy public void destroy(){ System.out.println("destroy"); }

依赖注入

@Autowried注解按类型自动装配

使用按名称装配使用@Qualifier注解指定名称

可以省略set方法

提供无参构造方法

@Autowired @Qualifier("bookDao") private BookDao bookDao;

使用@Value进行简单类型注入

@Value("dashadiao") private String name;

加载外部properties文件在配置类使用@PropertySource

如果有多个文件使用集合形式传入

@Configuration @ComponentScan("com.itheima") @PropertySource("jdbc.properties") public class SpringConfig { }

管理第三方bean

1.定义一个方法获得要管理的对象

2.添加@Bean,表示当前方法的返回值是一个bean

@Bean public DataSource dataSource(){ DruidDataSource ds = new DruidDataSource(); ds.setDriverClassName("com.mysql.jdbc.Driver"); ds.setUrl("jdbc:mysql://localhost:3306/softoa"); ds.setUsername("root"); ds.setPassword("123456789"); return ds; }

配置类使用@Import导入第三方配置类

@Configuration @Import({JdbcConfig.class}) public class SpringConfig { }

注入简单类型使用@Value

注入引用类型使用形参

@Bean public DataSource dataSource(BookDao bookDao){ DruidDataSource ds = new DruidDataSource(); return ds; }

AOP

AOP简介

AOP:面向切面编程

作用:在不惊动原始设计的基础上为其进行功能增强

连接点:程序执行过程中的任意位置,粒度为执行方法、抛出异常、设置变量

在SpringAOP中,理解为方法的执行

切入点:匹配连接点的式子

在SpringAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法

通知:在切入点处执行的操作,共性功能

在SpringAOP中,以方法形式呈现

通知类:定义通知的类

切面:描述通知与切入点的对应关系

AOP入门案例

1、导入坐标(pom.xml)

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

2、制作连接点方法

public void save() { System.out.println("-----------------"); System.out.println("book dao save ..."); } public void update(){ System.out.println("book dao update ..."); }

3、制作共性功能

public class MyAdvice { public void method(){ System.out.println("-----------------"); } }

4、定义切入点

使用@Pointcut注解

public class MyAdvice { @Pointcut("execution(void com.itheima.dao.BookDao.update())") private void pt(){} public void method(){ System.out.println("-----------------"); } }

5、绑定切入点与通知关系

@Component @Aspect public class MyAdvice { @Pointcut("execution(void com.itheima.dao.BookDao.update())") private void pt(){} @Before("pt()") public void method(){ System.out.println("-----------------"); } }

@Configuration @ComponentScan("com.itheima") @EnableAspectJAutoProxy public class SpringConfig { }

AOP的工作流程

1、Spring容器启动

2、读取切面配置中的切入点

3、初始化bean,判定bean对应的类方法是否匹配任意切入点

匹配失败,创建对象

匹配成功,创建原始对象的代理对象

4、获取bean执行方法

获取bean,调用方法执行,完成操作

获取的bean是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,完成操作

AOP切入点表达式

1、语法格式

动作关键字(访问修饰符 返回值 包名.类名.方法名(参数)异常名)

2、通配符

*:单个独立的任意符号

..:多个连续的任意符号

+:专用于匹配子类型

3、书写技巧

AOP通知类型

1、前置通知

@Before("pt()") public void before(){ System.out.println("前置通知"); }

2、后置通知

@After("pt()") public void after(){ System.out.println("后置通知"); }

3、环绕通知

@Around("pt()") public Object around(ProceedingJoinPoint pjp) throws Throwable { System.out.println("环绕通知1"); //原始操作调用 Object ret = pjp.proceed(); System.out.println("环绕通知2"); return ret; }

4、返回后通知

使用@AfterReturning

5、抛出异常后通知

使用@AfterThrowing

AOP通知获取数据

获取参数:所有通知

通知传入JoinPoint参数

@Before("pt()") public void before(JoinPoint jp){ System.out.println(Arrays.toString(jp.getArgs())); System.out.println("前置通知"); }

环绕通知直接使用ProceedingJoinPoint参数

获取返回值:环绕通知、返回后通知

Object ret = pjp.proceed();

获取异常:环绕通知、抛出异常后通知

Object ret = pjp.proceed();

事务

事务简介

事务作用:在数据层保障一系列的数据库操作同步

添加事务步骤

1、在方法或类上添加@Transactional

2、设置事务管理器

@Bean public PlatformTransactionManager transactionManager(DataSource dataSource){ DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(dataSource); return transactionManager; }

3、开启注解式事务驱动

@EnableTransactionManagement

事务角色

事务管理员:发起事务方,通常指业务层开启事务的方法

事务协调员:加入事务方,通常指数据层方法

事务相关配置

相关属性配置

事务传播行为

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值