目录
纯注解开发IOC和DI:
注解简介:
@Configuration 被此注解标记的类,声明是核心配置类 等同于applicationContext.xml
@ComponentScan 用在配置类上,开启注解扫描。使用basePackage属性指定扫描的包
@PropertySource 用在配置类上,加载properties文件。使用value属性指定properties文件路径
@Import 用在配置类上,引入子配置类。用value属性指定子配置类的Class
@Bean 用在配置类的方法上,把返回值声明为一个bean。用name/value属性指定bean的id
@Configuration:
1. 这是一个核心配置类,用来代替以前的applicationContext.xml
打注解: @Configuration
2. 这是一个@Component的衍生注解,所以只要这个类被扫描到
那么spring也同样会创建这个类的对象,并且管理起来。
@ComponentScan :
1. 用来指定扫描的包
2. 通过它的value属性或者basePackage属性来指定包名。
@PropertySource:
1. 用于导入外部的properties文件
2. 里面写properties的名字即可,如果在运行过程中报错:找不到文件或者文件无法打开之类,那么就在前面加上 classpath:@PropertySource("classpath:db.properties")
3. 定义变量,用于接收properties的内容
4. 在变量|属性身上,打注解 @Value("${KEY}")
@Bean注解: 方法级别的注解
作用: 把方法返回值声明为一个bean, 相当于<bean>标签
@Bean注解写在方法上,这些方法可以是核心配置类里面,也可以写在其他组件类里面
属性: value: bean的id,如果不设置,那么方法名就是bean的id
@Bean注解的方法可以有任意参数,这些参数即是bean所需要的依赖,默认采用byType方式注入
可以在方法参数上增加注解`@Qualifier`,用于byName注入
总结:
IOC:控制反转
@Component是通用的注解(表示核心配置文件中的bean标签,注明托管创建类的意思),包含以下
@Controller 针对web层
@Service 针对service层
@Repository 针对dao层
这三个注解性质一样,都是@Component衍生出来的注解,只是为了在不同的层上面更明确的显示,可以选择不同的注解使用,
value指的是id值,不指定会默认使用类名首字母小写作为id
@Scope 用来配置单例和多例
@singleton 单例 ,容器初始化时创建,容器关闭是销毁
@prototype 多例,获取对象时创建,长时间不使用时,垃圾回收销毁
@PostConstruct 创建对象时,调用指定的方法
@ProDestroy 对象销毁时调用指定的方法
DI:注入依赖
@RunWith(SpringJUnit4ClassRunner.class) 表示现在运行测试的运行环境是junit环境
@ContextConfiguration("classpath:applicationContext-All.xml")表示核心配置文件的路径,classpath: 是固定写法,表示在类路径下
@Autowired 表示自动注入,对象有一个时使用,有多个对象时会报错
有多个对象时@Autowired 和@Qualifier(标识符id)配合使用,根据id值去查找
@Resource = @Autwired + @Qualifier
@Value(“${properties里面的key}”) 表示注入普通的值(基本数据类型和String),需要导入properties文件
核心配置文件使用配置类的方式来写:
@Configuration 这个注解表示的是核心配置文件
@ComponentScan 作用在配置类上,开启注解扫描,basePackage表示只读扫描的包
@PropertySource 表示加载properties文件,value表示这个文件的路径
@Import引入子配置类,value表示子配置类的class
@Bean将返回值声明为一个bean,用name/value属性指定bean的id值
AOP:
面向切面编程,通过预编译方式或者运行期动态代理实现程序功能的统一维护的技术
AOP作用:
不修改源码的情况下,进行功能增强,通过动态代理实现
优势: 减少重复代码,提高开发效率,方便维护(增加日志输出,事务管理等)
底层实现:
实际上,Spring的AOP,底层是通过动态代理实现的。在运行期间,通过代理技术动态生成代理对象,代理对象方法执行时进行功能的增强介入,再去调用目标方法,从而完成功能增强。
动态代理技术:
JDK动态代理: 基于接口实现
Cglib动态代理: 基于子类实现
注: 目标对象有接口就使用JDK动态代理, 没有接口就使用cglib技术
Spring的AOP:
目标对象(Target): 要代理的/要增强的目标对象
代理对象(Proxy): 目标对象被AOP织入增强后 ,得到的一个代理对象
连接点(JoinPoint): 能够被拦截到的点,在spring里面指的是方法, 目标类中所有可以增强的方法就叫做连接点
切入点(PointCut): 已经增强的连接点叫做切入点,(要对那些连接点进行拦截的定义)
通知/增强(Advice): 对目标对象的方法进行功能增强的代码,(拦截到连接点后要做的事)
切面(Aspect): 切入点和通知的结合
织入(Weaving): 将增强/通知应用到目标对象(增强和切入点整合到一起)来创建代理对象的过程
Spring采用动态代理技术织入,AspectJ采用编译器织入和装载织入
Spring的AOP做的事情:
生成动态代理的过程(把通知织入到切入点的过程),是由Spring来实现的
Spring会监控切入点方法的执行,一旦发现切入点方法执行,使用代理机制动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码逻辑运行。
XML文件的AOP配置:----用来定义切面
aop:config : 用来做AOP配置的
aop:aspect :用来配置切面 ref : 表示用哪个类来做增强 这里表示使用myAdvice类来做增强
aop:before :表示要做前置增强(在执行目标代码之前,先执行增强的代码)
method: 表示用增强类中的哪个方法来增强。
pointcut: 切入点, 打算对什么方法做增强。
Xml声明事物控制:
一. 定义事物管理员:
- spring管理事物,一定是由管理员完成事物的操作(开启,提交,回滚事物)
- 根据dao层用到的技术不同,使用的管理员也不同
- Jdbctempalte或者myBatis的管理员DataSourceTransactionManager
- hibernate 的管理员是HibernateTransactionManager
- 事物管理员操作事物的时候需要用到连接对象,所以需要注入DataSource
<!-- 创建事物管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
二. 定义事物的规则:
- tx:advice 定义事物规则
- id 唯一标识
- Teansaction-manager 表示需要用到的管理员
- tx:attributes 配置事物规则,针对不同的方法配置不同的事物
- tx:method 具体的某一个方法; name的值(* 表示所有方法,xxx*表示以xxx开头的所有方法)
<!-- 定义事物的规则 xml--> <tx:advice id="transactionInterceptor" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" isolation="DEFAULT" propagation="MANDATORY" read-only="false" timeout="-1"/> </tx:attributes> </tx:advice>
三. 定义切面:
也就是表示那个方法需要用到事物
aop:config 配置切面
aop:advisor 专门用来 匹配衔接上面的事物的规则
advice-ref 事物的规则,id值
pointcut=“exeution(* com.itheima..*.*(..))” 切入点表达式,表示需要增强的方法的路径
<!-- 定义事物的切面--> <aop:config> <aop:advisor advice-ref="transactionInterceptor" pointcut="execution(* com..*.*(*))"/> </aop:config>
<aop:通知类型 method="通知中的方法" pointcut="切点表达式"></aop:通知类型>
通知类型:
Before 前置通知 (在切入点方法之前执行)
after-returning 后置通知 (切入点方法执行之后执行)
after-throwing 异常通知 (切入点抛出异常时执行)
after 最终通知 (无论切入点是否有异常都会执行)
around 环绕通知 (切入点执行前后都会执行)------需要手动调用目标方法
注解方式声明配置切面: @Aspect
切点表达式: execution([权限修饰符] 返回值类型 包名.类名.方法名(参数列表))
切点表达式:
权限修饰符可以省略不写
其他内容可以指定也可以: 返回值类型 包名.类名.方法名(参数列表) 都可以按需求用以下方式表示
* 表示任意/所有
xxx* 表示以xxx开头的任意/所有
. 表示当前的
.. 表示在当前以下的所有
IOC和AOP:
IOC使用注解方式需要打开扫描包的组件:
核心配置文件@Configuration类上的注解: @ComponentScan("com.itheima")//扫描包,组件
xml文件中打开: <context:component-scan base-package="com.xxx"/>
AOP使用注解需要定义事物管理器和打开事物开关:
核心配置文件@Configuration类上的注解:@EnableTransactionManagement//开启事物管理
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" value="dataSource"/>
</bean>
注解事务的配置:
1. 在类上或者方法上打注解 @Transactional
1.1 在类身上打,即表示该类中的所有方法都会应用上事务
1.2 在方法身上打,即表示只有这个方法会应用上事务。
2. 在xml里面打开注解的开关
<tx:annotation-driven transaction-manager="transactionManager"/>