Spring框架笔记 第二天
Spring的IOC的注解开发(******)
Spring的IOC的注解开发
1.创建Web项目,引入jar包
2.引入Spring的配置
在spring的压缩包中通过(spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html)路径,找到xsd-configuration.html,打开后找到
将context约束代码复制到自己的application.xml中
3.创建接口实现类
接口
public interface UserDao {
public void save();
}
实现类
/**
* 用户dao的实现
* @author 11312
*
*/
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("dao实现类执行了");
}
}
测试类
/**
* spring的IOC的注解开发测试类
* @author 11312
*
*/
public class Demo1 {
@Test
//传统方式
public void demo1() {
UserDao dao = new UserDaoImpl();
dao.save();
}
@Test
//注解方式
public void demo2() {
//加载配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.save();
}
}
4.开启Spring组件
<!-- Spring的IOC的注解的入门==== -->
<!-- 使用IOC的注解的开发,配置主键扫描(哪些包使用IOC的注解)==== -->
<context:component-scan base-package="com.spring.demo1"></context:component-scan>
将测试包的注解开发方式打开
5.在类上添加注解
/**
* 用户dao的实现
* @author 11312
*
*/
@Component("userDao")//相当于<Bean id="userDao" class="com.spring.demo1.UserDaoImpl">
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("dao实现类执行了");
}
}
在实现类的上方使用注解方式配置,就不用在appcationContext.xml文件中配置标签
6.注解方式设置属性的值
- 注解方式:使用注解方式可以没有set方法。
- 属性没有set的方法,直接在set方法上设置值
- 有set方法,直接在属性上设置值
@Value(“张三”)
private String name;
Spring的IOC的注解的详解
- 修饰一个类,将这个类交给spring管理
- 这个注解有三个衍生注解(功能类似,建议使用)
- @Controller:web层
- @Service :service层
- @Repository:dao层
2.属性注入的注解
- 普通属性:
- @value() :设置普通属性的值
- 对像类型属性:
- @Autowired:设置对象类型的属性的值。但是按照类型完成属性注入
- @Qualifier(value=“userDao”)
- 我们习惯按照名称完成属性注入:必须让@Autowired注解和Qualifier一起使用完成按照名称属性注入
- @resource:完成对象类型的属性的注入,按照名称完成属性注入
//@Component("userService")//相当于<Bean id="userDao" class="com.spring.demo1.UserDaoImpl">
@Repository("userService")
public class UserServiceImpl implements UserService {
@Value("lisi")
private String name;
@Autowired
@Qualifier(value="userDao")
//@Resource(name="userDao")
private UserDao dao;
@Override
public void save() {
System.out.println("service实现类执行了" + name);
dao.save();
}
}
Bean的其他的注解
- 生命周期相关的注解(了解)
- @PostConstruct:初始化方法
- @PreDestroy : 销毁方法
- Bean作用范围的注解
- @Scope :作用范围
- singleton :默认单例
- prototype :多例
- reuqest
- session
- globalsession
- @Scope :作用范围
IOC的XML和注解开发比较
-
适用场景
- XML:可以使用任何场景
- 结构清晰
- 注解:有些地方用不了,这个类不是自己提供的。
- 开发方便
- XML:可以使用任何场景
-
XML和注解整合开发
- 管理Bean的时候使用XML。属性注入的时候用注解。
Spring的AOP的XML开发(******)
AOP的概述
1.什么是AOP
AOP:面向切面编程。AOP解决OOP中遇到的一些问题,是OOP的扩展。
2.为什么学习AOP
对程序进行增强:不修改源码的情况下.
- AOP 可以进行权限校验,日志记录,性能监控,事务控制.
**3. Spring 的 AOP 的由来: **
AOP 最早由 AOP 联盟的组织提出的,制定了一套规范.Spring 将 AOP 思想引入到框架中,必须遵守 AOP 联盟 的规范.
4.底层实现
- 代理机制:
- Spring 的 AOP 的底层用到两种代理机制:
- JDK 的动态代理 :针对实现了接口的类产生代理.
- Cglib 的动态代理 :针对没有实现接口的类产生代理. 应用的是底层的字节码增强的技术 生成当前类 的子类对象.
Spring 底层 AOP 的实现原理:(了解)
JDK 动态代理增强一个类中方法:
public class MyJDKProxy implements InvocationHandler {
private UserDao userDao;
public MyJDKProxy(UserDao userDao) {
this.userDao = userDao;
}
// 编写工具方法:生成代理:
public UserDao createProxy() {
UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
userDao.getClass().getInterfaces(), this);
return userDaoProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("save".equals(method.getName())) {
System.out.println("权限校验================");
}
return method.invoke(userDao, args);
}
}
Cglib 动态代理增强一个类中的方法:
public class MyCglibProxy implements MethodInterceptor {
private CustomerDao customerDao;
public MyCglibProxy(CustomerDao customerDao) {
this.customerDao = customerDao;
}
// 生成代理的方法: public CustomerDao createProxy(){
// 创建 Cglib 的核心类: Enhancer enhancer = new Enhancer();
// 设置父类: enhancer.setSuperclass(CustomerDao.class);
// 设置回调: enhancer.setCallback(this);
// 生成代理:
CustomerDao customerDaoProxy = (CustomerDao) enhancer.create();return customerDaoProxy;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if ("delete".equals(method.getName())) {
Object obj = methodProxy.invokeSuper(proxy, args);
System.out.println("日志记录================");
return obj;
}
return methodProxy.invokeSuper(proxy, args);
}
}
Spring 的基于 AspectJ 的 AOP 开发
AOP 的开发中的相关术语:
Spring 使用 AspectJ 进行 AOP 的开发:XML 的方式(*****)
1.引入相应的 jar 包
- spring 的传统 AOP 的开发的包
- spring-aop-4.2.4.RELEASE.jar
- com.springsource.org.aopalliance-1.0.0.jar
- aspectJ 的开发包:
- com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
- spring-aspects-4.2.4.RELEASE.jar
2.引入 Spring 的配置文
引入 AOP 约束:
<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>
3.编写目标类
public interface OrderDao {
public void save();
public void update();
public void delete();
public void find();
}
public class OrderDaoImpl implements OrderDao {
@Override
public void save() {
System.out.println("保存订单...");
}
@Override
public void update() {
System.out.println("修改订单...");
}
@Override
public void delete() {
System.out.println("删除订单...");
}
@Override
public void find() {
System.out.println("查询订单...");
}
}
4.目标类的配置
<!-- 目标类================ -->
<bean id="orderDao" class="cn.itcast.spring.demo3.OrderDaoImpl"> </bean>
5.整合单元测试
//引入 spring-test.jar
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo3 {
@Resource(name = "orderDao")
private OrderDao orderDao;
@Test
public void demo1() {
orderDao.save();
orderDao.update();
orderDao.delete();
orderDao.find();
}
}
通知类型
前置通知 :在目标方法执行之前执行.
后置通知 :在目标方法执行之后执行
环绕通知 :在目标方法执行前和执行后执行
异常抛出通知:在目标方法执行出现 异常的时候 执行
最终通知 :无论目标方法是否出现异常 最终通知都会 执行
切入点表达式
1.编写一个切面
public class MyAspectXml {
// 前置增强
public void before() {
System.out.println("前置增强===========");
}
}
2.配置完成增强
<!-- 配置切面类 -->
<bean id="myAspectXml" class="cn.itcast.spring.demo3.MyAspectXml"></bean>
<!-- 进行 aop 的配置 -->
<aop:config>
<!-- 配置切入点表达式:哪些类的哪些方法需要进行增强 -->
<aop:pointcut
expression="execution(* cn.itcast.spring.demo3.OrderDao.save(..))"
id="pointcut1" />
<!-- 配置切面 -->
<aop:aspect ref="myAspectXml">
<aop:before method="before" pointcut-ref="pointcut1" />
</aop:aspect>
</aop:config>
3.其他的增强的配置
<!-- 配置切面类 -->
<bean id="myAspectXml" class="cn.itcast.spring.demo3.MyAspectXml"></bean>
<!-- 进行 aop 的配置 -->
<aop:config>
<!-- 配置切入点表达式:哪些类的哪些方法需要进行增强 -->
<aop:pointcut
expression="execution(*
cn.itcast.spring.demo3.*Dao.save(..))"
id="pointcut1" />
<aop:pointcut
expression="execution(* cn.itcast.spring.demo3.*Dao.delete(..))"
id="pointcut2" />
<aop:pointcut
expression="execution(* cn.itcast.spring.demo3.*Dao.update(..))"
id="pointcut3" />
<aop:pointcut
expression="execution(* cn.itcast.spring.demo3.*Dao.find(..))"
id="pointcut4" />
<!-- 配置切面 -->
<aop:aspect ref="myAspectXml">
<aop:before method="before" pointcut-ref="pointcut1" />
<aop:after-returning method="afterReturing"
pointcut-ref="pointcut2" />
<aop:around method="around" pointcut-ref="pointcut3" />
<aop:after-throwing method="afterThrowing"
pointcut-ref="pointcut4" />
<aop:after method="after" pointcut-ref="pointcut4" />
</aop:aspect>
</aop:config>