1 Spring框架概述
1.2 Spring的优点
2 入门案例:(IoC)
2.2目标类
2.4测试
3.1 目标类
3.3 service
3.5 测试
4.1属性依赖注入
4.1.2 setter方法
5 依赖注入装配Bean 基于注解
1 什么是AOP
3 AOP术语【掌握】
4.1手动方式
4.1.2 CGLIB字节码增强
4.2.1目标类
4.2.3Spring 配置
4.3全自动
4.3.2 测试
1 Spring框架概述
Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
方便解耦,简化开发 (高内聚低耦合)
spring工厂是用于生成bean
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
只需要通过配置就可以完成对事务的管理,而无需手动编程
Spring对Junit4支持,可以通过注解方便的测试Spring程序
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持
Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低
2 入门案例:(IoC)
2.2目标类
获得UserService实现类的实例
之后需要实例对象时,从spring工厂(容器)中获得,需要将实现类的全限定名称配置到xml文件中
public interface UserService { public void addUser();}public class UserServiceImpl implements UserService { @Override public void addUser() { System.out.println("a_ico add user"); }}位置:任意,开发中一般在classpath下(src)
内容:添加schema约束
2.4测试
@Test public void demo02(){ //从spring容器获得 //1 获得容器 String xmlPath = "com/itheima/a_ioc/beans.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); //2获得内容 --不需要自己new,都是从spring容器获得 UserService userService = (UserService) applicationContext.getBean("userServiceId"); userService.addUser(); 3.1 目标类
- 创建BookService接口和实现类
- 创建BookDao接口和实现类
- 将dao和service配置 xml文件
- 使用api测试
3.3 service
public interface BookService { public abstract void addBook();}public class BookServiceImpl implements BookService { // 方式1:之前,接口=实现类// private BookDao bookDao = new BookDaoImpl(); // 方式2:接口 + setter private BookDao bookDao; public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } @Override public void addBook(){ this.bookDao.save(); }}3.5 测试
@Test public void demo01(){ //从spring容器获得 String xmlPath = "com/itheima/b_di/beans.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); BookService bookService = (BookService) applicationContext.getBean("bookServiceId"); bookService.addBook(); }4.1属性依赖注入
- 依赖注入方式:手动装配 和 自动装配
- 手动装配:一般进行配置信息都采用手动
- 基于xml装配:构造方法、setter方法
- 基于注解装配:
目标类
public class User { private Integer uid; private String username; private Integer age; public User(Integer uid, String username) { super(); this.uid = uid; this.username = username; } public User(String username, Integer age) { super(); this.username = username; this.age = age; }4.1.2 setter方法
<!-- setter方法注入 * 普通数据 <property name="" value="值"> 等效 <property name=""> <value>值 * 引用数据 <property name="" ref="另一个bean"> 等效 <property name=""> <ref bean="另一个bean"/> --> <bean id="personId" class="com.itheima.f_xml.b_setter.Person"> <property name="pname" value="阳志"></property> <property name="age"> <value>1234</value> </property> <property name="homeAddr" ref="homeAddrId"></property> <property name="companyAddr"> <ref bean="companyAddrId"/> </property> </bean> <bean id="homeAddrId" class="com.itheima.f_xml.b_setter.Address"> <property name="addr" value="阜南"></property> <property name="tel" value="911"></property> </bean> <bean id="companyAddrId" class="com.itheima.f_xml.b_setter.Address"> <property name="addr" value="北京八宝山"></property> <property name="tel" value="120"></property> </bean>
5 依赖注入装配Bean 基于注解
开发中:使用注解 取代 xml配置文件。
@Component("id") 取代 <bean id="" class="">
@Repository :dao层
@Controller:web层
普通值:@Value(" ")
方式1:按照【类型】注入
方式2:按照【名称】注入1
@Qualifier("名称")
@Resource("名称")
初始化:@PostConstruct
5.作用域
注解使用前提,添加命名空间,让spring扫描含有注解类
<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"><!-- 组件扫描,扫描含有注解的类 --><context:component-scan base-package="com.itheima.g_annotation.a_ioc"></context:component-scan></beans>
1 什么是AOP
AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码
Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码
AspectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入
aop底层将采用代理机制进行实现。
接口 + 实现类 :spring采用 jdk 的动态代理Proxy。
3 AOP术语【掌握】
2.Joinpoint(连接点):所谓连接点是指那些可能被拦截到的方法。例如:所有的方法
4.advice 通知/增强,增强代码。例如:after、before
6.proxy 代理类
一个线是一个特殊的面。
4 AOP实现方式
4.1.1JDK动态代理
- JDK动态代理 对“装饰者”设计模式 简化。使用前提:必须有接口
2.切面类:用于存通知 MyAspect
public class MyAspect { public void before(){ System.out.println("鸡首"); } public void after(){ System.out.println("牛后"); }}4.测试
@Test public void demo01(){ UserService userService = MyBeanFactory.createService(); userService.addUser(); userService.updateUser(); userService.deleteUser(); }工厂类
public class MyBeanFactory { public static UserServiceImpl createService(){ //1 目标类 final UserServiceImpl userService = new UserServiceImpl(); //2切面类 final MyAspect myAspect = new MyAspect(); // 3.代理类 ,采用cglib,底层创建目标类的子类 //3.1 核心类 Enhancer enhancer = new Enhancer(); //3.2 确定父类 enhancer.setSuperclass(userService.getClass()); enhancer.setCallback(new MethodInterceptor(){ @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { //前 myAspect.before(); //执行目标类的方法 Object obj = method.invoke(userService, args); // * 执行代理类的父类 ,执行目标类 (目标类和代理类 父子关系) methodProxy.invokeSuper(proxy, args); //后 myAspect.after(); return obj; } }); //3.4 创建代理 UserServiceImpl proxService = (UserServiceImpl) enhancer.create(); return proxService; }}4.2.1目标类
public interface UserService { public void addUser(); public void updateUser(); public void deleteUser();}4.2.3Spring 配置
<!-- 1 创建目标类 --> <bean id="userServiceId" class="com.itheima.b_factory_bean.UserServiceImpl"></bean> <!-- 2 创建切面类 --> <bean id="myAspectId" class="com.itheima.b_factory_bean.MyAspect"></bean> <!-- 3 创建代理类 * 使用工厂bean FactoryBean ,底层调用 getObject() 返回特殊bean * ProxyFactoryBean 用于创建代理工厂bean,生成特殊代理对象 interfaces : 确定接口们 通过<array>可以设置多个值 只有一个值时,value="" target : 确定目标类 interceptorNames : 通知 切面类的名称,类型String[],如果设置一个值 value="" optimize :强制使用cglib <property name="optimize" value="true"></property> 底层机制 如果目标类有接口,采用jdk动态代理 如果没有接口,采用cglib 字节码增强 如果声明 optimize = true ,无论是否有接口,都采用cglib --> <bean id="proxyServiceId" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="interfaces" value="com.itheima.b_factory_bean.UserService"></property> <property name="target" ref="userServiceId"></property> <property name="interceptorNames" value="myAspectId"></property> </bean>
4.3全自动
- 从spring容器获得目标类,如果配置aop,spring将自动生成代理。
4.3.2 测试
@Test public void demo01(){ String xmlPath = "com/itheima/c_spring_aop/beans.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); //获得目标类 UserService userService = (UserService) applicationContext.getBean("userServiceId"); userService.addUser(); userService.updateUser(); userService.deleteUser(); }