摘要:
- Spring的IOC的注解开发
- 注解的入门
- 引入aop的包
- 引入context约束
- <context:component-scan />
- 使用注解开发
- @Component :定义Bean
- @Controller :WEB层
- @Service :Service层
- @Repository :DAO层
- 属性注入:
- 普通属性 :@Value
- 对象属性 :@Resource
- @Autowired :按类型注入属性,按名称@Qulifier
- @Component :定义Bean
- XML方式和注解方式比较
- XML方式 :适用性更广,结构更加清晰。
- 注解方式 :适用类是自己定义,开发更方便。
- XML和注解的整合开发
- XML定义类
- 注解属性注入
- 注解的入门
- Spring的AOP的基于AspectJ的XML的开发
- AOP的概述
- AOP:面向切面编程,是OOP的扩展和延伸,是用来解决OOP遇到问题。
- Spring的AOP
- 底层的实现
- JDK的动态代理
- Cglib的动态代理
- AOP的相关术语
- 连接点:可以被拦截的点。
- 切入点:真正被拦截的点。
- 通知:增强方法
- 引介:类的增强
- 目标:被增强的对象
- 织入:将增强应用到目标的过程。
- 代理:织入增强后产生的对象
- 切面:切入点和通知的组合
- AOP的入门开发
- 引入jar包
- 编写目标类并配置
- 编写切面类并配置
- 进行aop的配置
- 底层的实现
- AOP的概述
- <aop:config>
- <aop:pointcut expression=”execution(表达式)” id=”pc1”/>
- <aop:aspect >
- <aop:before method=”” pointcut-ref=”pc1”/>
- </aop:aspect>
- </aop:config>
- 通知类型
- 前置通知
- 后置通知
- 环绕通知
- 异常抛出通知
- 最终通知
切入点表达式写法
1.1 Spring的IOC注解开发
1.1.1 Spring的IOC注解开发入门
1.1.1.1创建Web项目引入jar包
- 在spring4版本中,除了引入基本的开发包外,还要引入aop包。
1.1.1.2引入spring的配置文件
- 在src下创建applicationContext.xml
- 引入约束:使用注解开发引入context约束
约束:spring-framework-4.2.4.RELEASE-dist\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
1.1.1.3 创建接口是实现类
1.1.1.4 开启Spring的组件扫描
<!-- Spring的IOC注解入门 -->
<!-- 使用IOC的注解开发,配置组件扫描(那些包下的类使用IOC注解) ======-->
<!-- 扫描是为了扫描类上的注解 -->
<context:component-scan base-package="com.itheima.spring"/>
1.1.1.5 在类上添加注解
@Component("userDao")//相当于<bean id="userDAO" class="com.itheima.spring.demo1.UserDaoImpl" >
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("Dao中保存的方法已经实现了。。。。"+name);
}
}
1.1.1.6 编写测试类
@Test
//Spring的IOC注解的方式
public void demo2() {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao=(UserDao) applicationContext.getBean("userDao");
userDao.save();
}
1.1.1.7 注解方式设置属性的值
注解方式:使用注解方式,可以没有set方法的
- 属性如果有set方法,需要将属性注入的注解添加到set方法中
- 属性如果没有set方法,需要将属性注入的注解添加到属性中
@Component("userDao")//相当于<bean id="userDAO" class="com.itheima.spring.demo1.UserDaoImpl" >
public class UserDaoImpl implements UserDao {
@Value("东子")
private String name;
/* public void setName(String name) {
this.name = name;
}*/
public void save() {
System.out.println("Dao中保存的方法已经实现了。。。。"+name);
}
}
1.1.2 Spring的IOC的注解的详解
1.1.2.1@Component:组件
1.1.2.2 属性注入的注解
普通属性:
- @value:设置普通属性的值
对象类型属性:
- @Autowired:设置对象类型的属性值。但是按照类型完成属性注入。
- 我们习惯是按照名称完成属性注入:必须让@Autowired注解和@Qualifier一起使用完成按照名称属性注入。
- @Resource:完成对象类型的属性注入,按照名称完成属性注入。
@Service("userService")//相当于<bean id="userService" class="com.itheima.spring.demo1.UserDaoImpl" >
public class UserServiceImpl implements UserService {
//注入DAO
/*@Autowired
@Qualifier(value="userDao")*/
@Resource(name="userDao")
private UserDao userDao;
public void save() {
System.out.println("Uservice的Dao。。。。");
userDao.save();
}
}
测试示例:
/**
* Spring注解开发的测试类
*/
public class SpringDemo1 {
@Test
//传统方式
public void demo1() {
UserDao userDao=new UserDaoImpl();
userDao.save();
}
@Test
//Spring的IOC注解的方式
public void demo2() {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao=(UserDao) applicationContext.getBean("userDao");
userDao.save();
}
@Test
//Spring的IOC注解的方式
public void demo3() {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService) applicationContext.getBean("userService");
userService.save();
}
}
1.1.2.3 Bean的其他注解
生命周期相关的注解(了解)
- @PostConstruct :初始化方法
- @PreDestory :销毁方法
Bean作用范围的注解
@Scope :作用范围
- singleton :默认单例
- prototype:多例
- request
- session
- globasession
@Service("customerService")//<bean id="" class="" init-method="init" destory-method="init"/>
@Scope("singleton")
public class CustomerService {
@PostConstruct//相当于init-method="init"
public void init() {
System.out.println("CustomerService的init方法执行了");
}
public void save() {
System.out.println("CustomerService的save方法执行了。。。");
}
@PreDestroy//相当于destory-method="init"
public void destory() {
System.out.println("CustomerService的destory方法执行了");
}
}
演示示例:
public class SpringDemo2 {
@Test
//生命周期演示
public void demo1() {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerService customerService=(CustomerService) applicationContext.getBean("customerService");
customerService.save();
}
}
1.1.3 IOC的XML和注解开发比较
1.1.3.1XML和注解的比较
试用场景
- XML:可以适用任何场景。结构清晰,维护方便。
- 注解:有些地方用不了,这个类不是自己提供的。开发方便。
1.1.3.2 XML和注解整合开发
XML完成管理Bean,注解完成属性注入。
- 配置applicayionContext.xml
- OrderDao
- ProductDao
- ProductService
测试示例:
1.2 Spring的AOP的XML开发(****)
1.2.1 AOP概述
1.2.1.1 什么是AOP
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
1.2.1.2 Spring底层的AOP实现原理
动态代理
- JDK动态代理 :只能对实现了接口的类产生代理
- Cglib动态代理(类似于javassist第三方代理技术) :对于没有实现接口的类产生代理对象,生成子类对象。
1.2.2 Spring的AOP底层实现(了解)
1.2.2.1 JDK动态代理
- 接口:
- 接口实现类:
- jdk动态代理类:
- 测试示例:
1.2.2.2 Cglib动态代理
Cglib:第三方开源代码生成库,动态添加类的属性和方法。
- 被代理的类:
- Cglib的动态代理
/**
* Cglib的动态代理
*/
public class CglibProxy implements MethodInterceptor{
private CustomerDao customerDao;
public CglibProxy(CustomerDao customerDao) {
super();
this.customerDao = customerDao;
}
/**
* Cglib产生代理的方法
*/
public CustomerDao creatProxy() {
//1.创建Cglib的核心类对象
Enhancer enhancer=new Enhancer();
//2.设置父类(Cglib是通过继承的方法取得代理对象)
enhancer.setSuperclass(customerDao.getClass());
//设置回调:(类似于InvocationHandler对象)
enhancer.setCallback(this);
//返回代理对象
CustomerDao proxy = (CustomerDao) enhancer.create();
return proxy;
}
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methosProxy) throws Throwable {
//判断方法是否为insert
if("insert".equals(method.getName())) {
System.out.println("增强了。。。。。。。。。。");
return methosProxy.invokeSuper(proxy, args);
}
return methosProxy.invokeSuper(proxy, args);
}
}
- 测试示例:
1.2.3 Spring的AOP的开发(AspectJ的XML的方式)
1.2.3.1 Spring的AOP的简介
AOP思想最早是由AOP联盟组织提出的。Spring是使用这种思想最好的框架。
Spring的AOP有自己实现的方式(非常繁琐)。AspectJ是一个AOP的框架,Spring引入AspectJ作为自身AOP的开发。
Spring两套AOP开发方式。
- Spring传统方式(弃用)
- Spring基于AspectJ的AOP的开发(使用)
1.2.3.2 AOP开发中相关术语:
1.2.4 Spring的AOP的入门(AspectJ的XML的方式)
1.2.4.1 创建Web项目,引入jar包
- 引入基本开发包
- 引入AOP开发的相关jar包
1.2.4.2 引入Spring的配置文件
- 引入aop的约束
约束:spring-framework-4.2.4.RELEASE-dist\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
1.2.4.3 编写目标类并完成配置
- 接口
- 接口实现类
- 配置:
1.2.4.4 编写测试类
- Spring整合Junit单元测试
1.2.4.5 编写切面类
- 编写切面类
- 将切面类交给spring
1.2.4.6 通过AOP的配置实现
1.2.5. Spring中通知类型
1.2.5.1 前置通知:在目标方法执行之前进行操作
- 前置通知:获得切入点信息
1.2.5.2 后置方法:在目标方法执行之后进行操作
- 后置通知:获得方法的返回值
1.2.5.3 环绕通知:在目标方法执行之前和之后进行操作
1.2.5.4 异常抛出通知:在程序出现异常的时候,进行的操作
- 获得异常信息
1.2.5.5 最终通知:无论代码是否有异常,总会执行。
1.2.5.6 引介通知(不会用)
代码:
- 切面类:
/*
* 切面类
*/
public class MyAspectXML {
//前置通知
public void cheak(JoinPoint joinPoint) {
System.out.println("cheak run============"+joinPoint);
}
//后置通知
public void writeLog(Object resault) {
System.out.println("日志记录======"+resault);
}
//环绕通知
public Object round(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕前通知。。。。。。。。");
Object obj = joinPoint.proceed();
System.out.println("环绕后通知。。。。。。。。");
return obj;
}
//异常抛出通知
public void afterThrowing(Throwable ex) {
System.out.println("异常抛出了。。。"+ex.getMessage());
}
//最终通知
public void after() {
System.out.println("最终通知-----------");
}
}
- 配置:
1.2.6 Spring的切入点表达式写法
1.2.6.1切入点表达式语法
基于exception的函数完成的
语法:
- Public void com.itheima.spring.CustomerDao.save(..)
- * *.*.*Dao.save(..)
- * come.itheima.spring.CustomerDao+.save(..)
- * com.itheima.spring..*.*(..)