-
Spring整合Mybatis开发过程中 不使⽤@Repository @Component
-
@Scope注解
-
作⽤:控制简单对象创建次数
-
注意:不添加@Scope Spring提供
默认值 singleton
-
@Lazy注解
-
作⽤:延迟创建单实例对象
-
注意:⼀旦使⽤了@Lazy注解后,
Spring会在使⽤这个对象时候,进⾏这个对象的创建
- ⽣命周期⽅法相关注解
- 初始化相关⽅法 @PostConstruct
InitializingBean
- 销毁⽅法 @PreDestroy
DisposableBean
-
注意:
-
上述的2个注解并不是Spring提供的,JSR(JavaEE规范)520
-
再⼀次的验证,通过注解实现了接⼝的契约性
2. 注⼊相关注解
- ⽤户⾃定义类型 @Autowired
@Autowired细节
- Autowired注解基于类型进⾏注⼊ [推荐]
基于类型的注⼊:注⼊对象的类型,必须与⽬标成员变量类型相同或者是其⼦类
(实现类)
- Autowired Qualifier 基于名字进⾏注⼊ [了解]
基于名字的注⼊:注⼊对象的id值,必须与Qualifier注解中设置的名字相同
- Autowired注解放置位置
a) 放置在对应成员变量的set⽅法上
b) 直接把这个注解放置在成员变量之上,Spring通过反射直接对成员变量进⾏注⼊(赋值)[推荐]
- JavaEE规范中类似功能的注解
JSR250 @Resouce(name=“userDAOImpl”) 基于名字进⾏注⼊
@Autowired()
@Qualifier(“userDAOImpl”)
注意:如果在应⽤Resource注解时,名字没有配对成功,那么他会继续按照类型进⾏注⼊。
JSR330 @Inject 作⽤ @Autowired完全⼀致 基于类型进⾏注⼊ —》EJB3.0
javax.inject
javax.inject
1
-
JDK类型
-
@Value
- 设置xxx.properties
id = 10
name = achang
- Spring的⼯⼚读取这个配置⽂件
<context:property-placeholder location=“”/>
- 代码
属性 @Value(“${key}”)
- @PropertySource
- 作⽤:
⽤于替换Spring配置⽂件中的<context:property-placeholder location=“”/>标签
-
开发步骤
-
设置xxx.properties
id = 10
name = achang
-
应⽤@PropertySource
-
代码
属性 @Value()
-
@Value注解使⽤细节
-
@Value注解
不能应⽤在静态成员变量上
如果应⽤,赋值(注⼊)失败
@Value注解+Properties这种⽅式,不能注⼊集合类型
Spring提供新的配置形式 YAML YML (SpringBoot)
3. 注解扫描详解
<context:component-scan base-package=“com.achang”/>
当前包 及其 ⼦包
1. 排除⽅式
<context:component-scan base-package=“com.achang”>
<context:exclude-filter type=“” expression=“”/>
type:
assignable:排除特定的类型 不进⾏扫描
annotation:排除特定的注解 不进⾏扫描
aspectj:切⼊点表达式
包切⼊点: com.achang.bean…*
类切⼊点: *…User
regex:正则表达式
custom:⾃定义排除策略框架底层开发
</context:component-scan>
排除策略可以叠加使⽤
<context:component-scan base-package=“com.achang”>
<context:exclude-filter type=“assignable” expression=“com.achang.bean.User”/>
<context:exclude-filter type=“aspectj” expression=“com.achang.injection… *”/>
</context:component-scan>
2. 包含⽅式
<context:component-scan base-package=“com.achang” use-default-filters=“false”>
<context:include-filter type=“” expression=“”/>
</context:component-scan>
- use-default-filters=“false”
作⽤:让Spring默认的注解扫描⽅式 失效。
- <context:include-filter type=“” expression=“”/>
作⽤:指定扫描那些注解
type:assignable:排除特定的类型 不进⾏扫描
annotation:排除特定的注解 不进⾏扫描
aspectj:切⼊点表达式
包切⼊点: com.baizhiedu.bean…*
类切⼊点: *…User
regex:正则表达式
custom:⾃定义排除策略框架底层开发
包含的⽅式⽀持叠加
<context:component-scan base-package=“com.achang” use-default-filters=“false”>
<context:include-filter type=“annotation” expression=“org.springframework.stereotype.Repository”/>
<context:include-filter type=“annotation” expression=“org.springframework.stereotype.Service”/>
</context:component-scan>
4. 对于注解开发的思考
- 配置互通
//Spring注解配置 配置⽂件的配置 互通
@Repository
public class UserDAOImpl{
}
public class UserServiceImpl{
private UserDAO userDAO;
set/get
}
- 什么情况下使⽤注解 什么情况下使⽤配置⽂件
@Component 替换 <bean
基础注解(@Component @Autowired @Value) 程序员开发类型的配置
- 在程序员开发的类型上 可以加⼊对应注解 进⾏对象的创建
User UserService UserDAO UserAction
- 应⽤其他⾮程序员开发的类型时,还是需要使⽤<bean 进⾏配置的
后续使用@Configuration + @Bean
SqlSessionFactoryBean MapperScannerConfigure
5. SSM整合开发(半注解开发)
-
搭建开发环境
-
引⼊相关jar 【SSM POM】
-
引⼊相关配置⽂件
-
applicationContext.xml
-
struts.xml
-
log4.properties
-
XXXMapper.xml
-
初始化配置
-
Web.xml Spring (ContextLoaderListener)
-
Web.xml Struts Filter
-
编码
注解扫描
<context:component-scan base-package=“”/>
- DAO (Spring+Mybatis)
-
配置⽂件的配置
-
DataSource
-
SqlSessionFactory ----> SqlSessionFactoryBean
-
dataSource
-
typeAliasesPackage
-
mapperLocations
-
MapperScannerConfigur —> DAO接⼝实现类
-
编码
-
entity
-
table
-
DAO接⼝
-
实现Mapper⽂件
- Service
- 原始对象 —》 注⼊DAO
@Service —> @Autowired
-
额外功能 —》 DataSourceTransactionManager —> dataSource
-
切⼊点 + 事务属性
@Transactional(propagation,readOnly…)
- 组装切⾯
<tx:annotation-driven
- Controller (Spring+Struts2)
- @Controller
@Scope(“prototype”)
public class RegAction implements Action{
@Autowired
private UserService userServiceImpl;
}
- struts.xml
1. 配置Bean
Spring在3.x提供的新的注解,⽤于替换XML配置⽂件。
@Configuration
public class AppConfig{}
- 配置Bean在应⽤的过程中
替换了XML
具体什么内容呢?
- AnnotationConfigApplicationContext
- 创建⼯⼚代码
ApplicationContext ctx = new AnnotationConfigApplicationContext();
-
指定配置⽂件
-
指定配置类
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
- 指定配置类所在的路径
ApplicationContext ctx = new AnnotationConfigApplicationContext(“com.achang”);
-
配置Bean开发的细节分析
-
基于注解开发使⽤⽇志
不能集成Log4j
集成logback
- 引⼊相关jar
org.slf4j
slf4j-api
1.7.25
org.slf4j
jcl-over-slf4j
1.7.25
ch.qos.logback
logback-classic
1.2.3
ch.qos.logback
logback-core
1.2.3
org.logback-extensions
logback-ext-spring
0.1.4
- 引⼊logback配置⽂件 (logback.xml)
%d{yyyy-MM-dd HH:mm:ss.SSS}[%thread] %-5level %logger{50} - %msg%n
-
@Configuration注解的本质
-
本质:也是
@Component注解的衍⽣注解
-
可以应⽤<context:component-scan进⾏扫描
2. @Bean注解
@Bean注解在配置bean中进⾏使⽤,等同于XML配置⽂件中的<bean标签
1. @Bean注解的基本使⽤
- 对象的创建
- 简单对象
直接能够通过new⽅式创建的对象
User UserService UserDAO
- 复杂对象
不能通过new的⽅式直接创建的对象
Connection SqlSessionFactory
- @Bean注解创建复杂对象的注意事项
遗留系统整合
@Bean
public Connection conn1() {
Connection conn = null;
try {
ConnectionFactoryBean factoryBean = new ConnectionFactoryBean();
conn = factoryBean.getObject();
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
- ⾃定义id值
@Bean(“id”)
- 控制对象创建次数
@Bean
@Scope(“singleton|prototype”) 默认值 singleton
2. @Bean注解的注⼊
- ⽤户⾃定义类型
@Bean
public UserDAO userDAO() {
return new UserDAOImpl();
}
@Bean
public UserService userService(UserDAO userDAO) {
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDAO(userDAO);
return userService;
}
//简化写法
@Bean
public UserService userService() {
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDAO(userDAO());
return userService;
}
- JDK类型的注⼊
@Bean
public Customer customer() {
Customer customer = new Customer();
customer.setId(1);
customer.setName(“xiaohei”);
return customer;
}
- JDK类型注⼊的细节分析
如果直接在代码中进⾏set⽅法的调⽤,会存在耦合的问题
@Configuration
@PropertySource(“classpath:/init.properties”)
public class AppConfig1 {
@Value(“${id}”)
private Integer id;
@Value(“${name}”)
private String name;
@Bean
public Customer customer() {
Customer customer = new Customer();
customer.setId(id);
customer.setName(name);
return customer;
}
}
3. @ComponentScan注解
@ComponentScan注解在配置bean中进⾏使⽤,等同于XML配置⽂件
中的
⽬的:进⾏相关注解的扫描 (@Component @Value …@Autowired)
context:component-scan标签
1. 基本使⽤
@Configuration
@ComponentScan(basePackages = “com.achang.scan”)
public class AppConfig2 {
}
<context:component-scan base-package=“”/>
2. 排除、包含的使⽤
- 排除
<context:component-scan base-package=“com.achang”>
<context:exclude-filter type=“assignable” expression=“com.achang.bean.User”/>
</context:component-scan>
@ComponentScan(basePackages = “com.achang.scan”,excludeFilters ={@ComponentScan.Filter(type=FilterType.ANNOTATION,value={Service.class}),
@ComponentScan.Filter(type=FilterType.ASPECTJ,pattern = “*…User1”)})
排除方式:↓
type = FilterType.ANNOTATION value
.ASSIGNABLE_TYPE value
.ASPECTJ pattern
.REGEX pattern
.CUSTOM value
- 包含
要先设置use-default-filters="false"
<context:component-scan base-package=“com.achang” use-default-filters=“false”>
<context:include-filter type=“” expression=“”/>
</context:component-scan>
@ComponentScan(basePackages = “com.achang.scan”,useDefaultFilters = false,includeFilters = {@ComponentScan.Filter(type=FilterType.ANNOTATION,value={Service.class})})
排除方式:↓
type = FilterType.ANNOTATION value
.ASSIGNABLE_TYPE value
.ASPECTJ pattern
.REGEX pattern
.CUSTOM value
4. Spring⼯⼚创建对象的多种配置⽅式
1. 多种配置⽅式的应⽤场景
2. 配置优先级
@Component及其衍⽣注解 < @Bean < 配置⽂件bean标签
优先级⾼的配置 覆盖优先级低配置
@Component
public class User{
}
@Bean
public User user(){
return new User();
}
配置覆盖:id值 保持⼀致
- 解决基于注解进⾏配置的耦合问题
@Configuration
//@ImportResource(“applicationContext.xml”)
public class AppConfig4 {
@Bean
public UserDAO userDAO() {
return new UserDAOImpl();
}
}
@Configuration
@ImportResource(“applicationContext.xml”)
//通过一个新的xml配置文件,掩盖,注释掉上面久的,保持原有不变
public class AppConfig5{
}
通过xml配置文件对上面需要修改的userDao的实现进行掩盖
applicationContext.xml:
5. 整合多个配置信息
- 为什么会有多个配置信息
拆分多个配置bean的开发,是⼀种模块化开发的形式
,也体现了⾯向对象各司其职
的设计思想
-
多配置信息整合的⽅式
-
多个配置Bean的整合
-
配置Bean与@Component相关注解的整合
-
配置Bean与SpringXML配置⽂件的整合
-
整合多种配置需要关注那些要点
-
如何使多配置的信息 汇总成⼀个整体
-
如何实现跨配置的注⼊
1. 多个配置Bean的整合
-
多配置的信息汇总
-
base-package进⾏多个配置Bean的整合
- @Import
-
可以创建对象
-
多配置bean的整合
- 在⼯⼚创建时,指定多个配置Bean的Class对象 【了解】
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig1.class,AppConfig2.class);
- 跨配置进⾏注⼊
在应⽤配置Bean的过程中,不管使⽤哪种⽅式进⾏配置信息的汇总,其操作⽅式都是通过成员变量加⼊@Autowired注解
完成。
@Configuration
@Import(AppConfig2.class)
public class AppConfig1 {
@Autowired
private UserDAO userDAO;
@Bean
public UserService userService() {
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDAO(userDAO);
return userService;
}
}
@Configuration
public class AppConfig2 {
@Bean
public UserDAO userDAO() {
return new UserDAOImpl();
}
}
2. 配置Bean与@Component相关注解的整合
@Component()|@Repository()
public class UserDAOImpl implements UserDAO{
}
@Configuration
@ComponentScan(“”)
public class AppConfig3 {
@Autowired
private UserDAO userDAO;
@Bean
public UserService userService() {
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDAO(userDAO);
return userService;
}
}
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig3.class);
3. 配置Bean与配置⽂件整合
- 遗留系统的整合 2. 配置覆盖
public class UserDAOImpl implements UserDAO{
}
@Configuration
@ImportResource(“applicationContext.xml”)
public class AppConfig4 {
@Autowired
private UserDAO userDAO;
@Bean
public UserService userService() {
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDAO(userDAO);
return userService;
}
}
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig4.class);
6. 配置Bean底层实现原理
Spring在配置Bean中加⼊了@Configuration注解后,底层就会通过Cglib的代理⽅式
,来进⾏对象相关的配置、处理
7. 四维⼀体的开发思想
- 什么是四维⼀体
Spring开发⼀个功能的4种形式,虽然开发⽅式不同,但是最终效果是⼀样的。
-
基于schema
-
基于特定功能注解
-
基于原始<bean
-
基于@Bean注解
-
四维⼀体的开发案例
context:property-placehoder标签的底层是通过PropertySourcePlaceholderConfigure类来完成注入的
-
<context:property-placehoder location=“”/>
-
@PropertySource(“”) 【推荐】
- @Bean 【推荐】
8. 纯注解版AOP编程
1. 搭建环境
-
应⽤配置Bean
-
注解扫描
2. 开发步骤
- 原始对象
@Service|@Component
public class UserServiceImpl implements UserService{
}
- 创建切⾯类 (额外功能 切⼊点 组装切⾯)
@Aspect
@Component
public class MyAspect {
@Around(“execution(* login(…))”)//切入点
public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
//额外功能
System.out.println(“----aspect log ------”);
Object ret = joinPoint.proceed();
return ret;
}
}
- Spring的配置⽂件中
<aop:aspectj-autoproxy />
@EnableAspectjAutoProxy —> 配置Bean
3. 注解AOP细节分析
Spring AOP 代理默认实现 JDK
SpringBOOT AOP 代理默认实现 Cglib
- 代理创建⽅式的切换 JDK Cglib
<aop:aspectj-autoproxy proxy-target-class=true|false />
@EnableAspectjAutoProxy(proxyTargetClass)
- SpringBoot AOP的开发⽅式
@EnableAspectjAutoProxy 已经设置好了
- 原始对象
@Service(@Component)
public class UserServiceImpl implements UserService{
}
- 创建切⾯类 (额外功能 切⼊点 组装切⾯)
@Aspect
@Component
public class MyAspect {
@Around(“execution(* login(…))”)
public Object arround(ProceedingJoinPoint joinPoint) throws
Throwable {
System.out.println(“----aspect log ------”);
Object ret = joinPoint.proceed();
return ret;
}
}
9. 纯注解版Spring+MyBatis整合
- 基础配置 (配置Bean)
1、连接池
<bean id=“dataSource”
class=“com.alibaba.druid.pool.DruidDataSource”>
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(“”);
dataSource.setUrl();
…
return dataSource;
}
2、SqlSessionFactoryBean
<bean id=“sqlSessionFactoryBean”
class=“org.mybatis.spring.SqlSessionFactoryBean”>
classpath:com.achang.mapper.*Mapper.xml