Spring框架笔记 第二天

Spring的IOC的注解开发(******)

Spring的IOC的注解开发

1.创建Web项目,引入jar包
Spring框架笔记 第二天
2.引入Spring的配置
在spring的压缩包中通过(spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html)路径,找到xsd-configuration.html,打开后找到
Spring框架笔记 第二天
将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的注解的详解

[email protected]:组件

  • 修饰一个类,将这个类交给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

IOC的XML和注解开发比较Spring框架笔记 第二天

  • 适用场景
    • XML:可以使用任何场景
      • 结构清晰
    • 注解:有些地方用不了,这个类不是自己提供的。
      • 开发方便
  • XML和注解整合开发
    • 管理Bean的时候使用XML。属性注入的时候用注解。

Spring的AOP的XML开发(******)

AOP的概述

1.什么是AOP
Spring框架笔记 第二天
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框架笔记 第二天

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
      Spring框架笔记 第二天

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();
	}
}

通知类型

前置通知 :在目标方法执行之前执行.
后置通知 :在目标方法执行之后执行
环绕通知 :在目标方法执行前和执行后执行
异常抛出通知:在目标方法执行出现 异常的时候 执行
最终通知 :无论目标方法是否出现异常 最终通知都会 执行

切入点表达式

Spring框架笔记 第二天
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>