栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring框架

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring框架

一、概述
  1. Spring是轻量级的开源的JavaEE框架。
  2. Spring可以解决企业应用开发的复杂性
  3. Spring有两个核心的部分:IOC 和 AOP
  • IOC:控制反转,把创建对象过程交给Spring进行管理
  • AOP:面向切面,不修改源代码进行功能管理

Spring特点:

  1. 方便解耦,简化开发
  2. AOP编程支持
  3. 方便程序测试
  4. 方便和其他框架进行整合
  5. 方便进行事务操作
  6. 降低API开发难度

jar包下载地址:https://repo.spring.io/release/org/springframework/spring/

案例1

1 创建spring的核心配置文件



	
	

2 创建实体类

public class Student {
    private Integer sid;
    private String sname;
    private String sex;
    private Integer sage;
    private Boolean sdy;
    ...
}

3 在核心配置文件中通过bean标签来创建对象



    
    
    
    
    


    
    
    
    
    

4 测试类

//创建spring上下文对象  关联核心配置文件
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("com/zhiyou/ioc/spring1.xml");
//通过上下文对象的getbean方法 由bean的name值获取javabean对象
Student stu1=(Student)context.getBean("s1");
System.out.println(stu1);
Student stu2=(Student)context.getBean("s2");
System.out.println(stu2);
context.close();

 二、IOC容器
  1. IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
  2. Spring提供IOC容器实现的两种方式:(两个接口)
  1. BeanFactory,IOC容器基本实现,是Spring内部使用接口,不提供给开发人员进行使用

      *加载配置文件时不会创建对象,在获取对象时才创建对象

     2.APPlicationContext ,BeanFactory的子接口,提供更多强大的功能,一般由开发人员使用

        *加载配置文件时就会把在配置文件对象进行创建

3、APPlicationContext接口的实现类

1)FileSystemXmAPPlicationContext     2)ClassPathXmAPPlicationContext

写路径时如果是FileSystemXmAPPlicationContext 则写盘符所在路径

写路径时如果是ClassPathXmAPPlicationContext  则写src 下的路径

1、xml配置方式创建对象
2、xml方式注入属性 1) set方式注入属性

前提:实体类必须有set方法

property标签    name为属性的名字  value为属性的值


    
    
    
    
    
2)构造方法的方式注入属性

ioc创建对象时,会默认使用实体类中的无参构造方法

用构造方法赋值时,需要声明有参的构造方法


    
    
    
    
    
3、注入其他类型的属性 1)null值

     
2)对象类型

用ref引入另一个bean


    
    
    
    
    
    
    
    
    



    
    
    
3)数组和集合类型属性

    
    
    


    
    
    


    
    
    



    
    
    
    
    
    
        
            111
            112
            113
            114
        
    

    
    
        
            
            
            
        
    

    
    
        
            
            
            
            
            
            
        
    

    
    
        
            21
            31
            41
        
    

 
    
        
            22
            32
            42
            22
            32
            42
        
    

    
    
        
            
            
            
        
    
4、bean的作用域

在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例 scope 属性值


    
    
    
    
    

作用域

描述

单例(singleton)

(默认)每一个Spring IoC容器都拥有唯一的一个实例对象

原型(prototype)

一个Bean定义,任意多个对象

请求(request)

一个HTTP请求会产生一个Bean对象,也就是说,每一个HTTP请求都有自己的Bean实例。只在基于web的Spring ApplicationContext中可用

会话(session)

限定一个Bean的作用域为HTTPsession的生命周期。同样,只有基于web的Spring ApplicationContext才能使用

全局会话(global session)

限定一个Bean的作用域为全局HTTPSession的生命周期。通常用于门户网站场景,同样,只有基于web的Spring ApplicationContext可用

5、bean的懒加载

 bean的懒加载:默认情况下scope=singleton的bean 项目启动spring容器加载核心配置文件就会创建bean对应的对象 
      开头通过lazy-init="true"属性来指定 bean标签第一次被调用时才创建对象


    
    
    
    
    
6、bean的生命周期

生命周期:从对象创建到对象销毁的过程

(1)通过构造器创建 bean 实例(无参数构造)

(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)

(3)调用 bean 的初始化的方法(需要进行配置初始化的方法)

(4)bean 可以使用了(对象获取到了)

(5)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

其中初始化和销毁方法需要自定义,并且在配置文件中配置,用bean标签中属性指定

7、属性的自动装配(自动关联的属性赋值)

autowire="byName":自动给对象类型的属性赋值:bean名字和属性名一致


    
    
    
    
    
    

  autowire="byType":如果找到一个指定类型的bean 直接赋值
  如果找到多个 赋值bean的名字与属性名相同的
  如果找到多个 但没有bean的名字与属性名字相同的  报错:UnsatisfiedDependencyException


    
    
    
    
    
    
8、注解形式的ioc

Spring 创建对象提供注解

(1)@Component

(2)@Service

(3)@Controller

(4)@Repository

Spring 属性注入提供注解 

(1)@Autowired:根据属性类型进行自动装配

(2)@Qualifier:根据名称进行注入,要和@Autowired一起使用

(3)@Resource:可以根据类型注入,也可以根据名称注入

(4)@Value:注入普通类型属性

1)在核心配置文件中引入context的命名空间和xsd

    
2)使用context标签指定添加了注解的实体类的位置
3)在实体类上添加注解
//@Repository    //创建bean的注解:给dao持久层的类添加的注解
//@Controller    //创建bean的注解:给controller控制层的类添加的注解
//@Service       //创建bean的注解:给service业务层的类添加的注解
@Component("s2")  //创建bean的注解:不确定当前bean具体属于那一层  可以加属性:用于指定bean的名字  不加默认是类名首字母小写
//@Scope("prototype") //指定bean的作用域
@Lazy//懒加载  只适用于单例模式
public class Student {
    {
        System.out.println("构造代码块!!");
    }
    //@Value("1001")给属性赋值:可以加载属性上  也可以加在set方法上
    @Value("1001")
    private Integer sid;
    @Value("韩庚")
    private String sname;
    @Value("男")
    private String sex;
    @Value("19")
    private Integer sage;
    private Boolean sdy;

    //@Autowired  //自动装配:策略和byType类似
    //@Resource(name="teacher")//自动装配:name指定bean的名字
    @Resource
    private Teacher teacher;
    public Teacher getTeacher() {
        return teacher;
    }
    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
    public Integer getSid() {
        return sid;
    }
    public void setSid(Integer sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Integer getSage() {
        return sage;
    }
    public void setSage(Integer sage) {
        this.sage = sage;
    }
    public Boolean getSdy() {
        return sdy;
    }
    @Value("true")
    public void setSdy(Boolean sdy) {
        this.sdy = sdy;
    }	
    @Override
    public String toString() {
        return "Student [sid=" + sid + ", sname=" + sname + ", sex=" + sex + ", sage=" + sage + ", sdy=" + sdy
            + ", teacher=" + teacher + "]";
    }
    public Student(Integer sid, String sname, String sex, Integer sage, Boolean sdy) {
        super();
        this.sid = sid;
        this.sname = sname;
        this.sex = sex;
        this.sage = sage;
        this.sdy = sdy;
    }
    public Student() {
        super();
    }

    @PostConstruct
    public void initMethod(){
        System.out.println("public void initMethod()");
    }
    @PreDestroy
    public void destroyMethod(){
        System.out.println("public void destroyMethod()");
    }
}
4)@Resource和@Autowired的区别

其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource

@Resource默认按照ByName方式注入,有name和type两个属性,分别是按照名称和按照类型注入,如果这两个属性都没有指定就会按默认方式注入,也可以两个同时指定

@Autowired默认按照ByType方式注入,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果想要按照ByName方式需要配合@Qualifier注解一起使用,指定@Qualifier的value属性值为要注入的bean的名字

三、AOP容器

(1)面向切面编程(方面),利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得 业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

(2)通俗描述:不通过修改源代码方式,在主干功能里面添加新功能

1、aop术语

(1)连接点:类里面哪些方法可以被增强,这些方法成为连接点

(2)切入点:实际被真正增强的方法,成为切入点

(3)通知(增强):实际增强的逻辑部分称为通知(增强)

     通知的类型:*前置通知 *后置通知 *环绕通知 *异常通知 *最终通知

(4)切面(是动作):把通知应用到切入点的过程

2、切入点表达式

(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强

(2)语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )

* 代表全部

举例 1:对 com.zhiyou.dao.BookDao 类里面的 add 进行增强

execution(* com.zhiyou.dao.BookDao.add(..))

举例 2:对 com.zhiyou.dao.BookDao 类里面的所有的方法进行增强

execution(* com.zhiyou.dao.BookDao.* (..))

举例 3:对 com.zhiyou.dao 包里面所有类,类里面所有方法进行增强

execution(* com.zhiyou.dao.*.* (..))

3、通知类型

@Before注解表示作为前置通知

@After注解表示作为最终通知

@AfterReturning注解表示作为后置通知

@AfterThrowing注解表示作为异常通知

@Around注解表示作为环绕通知

注意:After与AfterReturning的区别:

After无论如何都执行,也称为最终通知

AfterReturning发生异常时不执行,称为后置通知或返回通知

4、基于xml配置方式的aop 1)导入jar包

 2)创建目标实体类定义方法,并抽取接口
public class Student implements Serializable, StudentInterface{
	private String sname;

	public int addHao(int a,int b){
		System.out.println("学生'"+sname+"'正在算术:"+a+"+"+b+"="+(a+b));
		return a+b;
	}
	public void eatHao(String food){
		System.out.println("学生'"+sname+"'正在吃饭:'"+food+"'真香!");
	}
	public void smokeCha(String name){
		System.out.println("学生'"+sname+"'正在吸烟:'"+name+"'吞云吐雾!");
	}
	public void sleepHao(){
		System.out.println("学生'"+sname+"'正在休息:劳逸结合!");
	}
	public void gameCha(String gname){
		System.out.println("学生'"+sname+"'正在玩游戏:玩物丧志!");
	}
    ....
}
3)创建代理实体类,配置通知方法
//创建实体类 封装所有的辅助功能
public class MyAdvice {
	public void after1AdviceMethod(){
		System.out.println("..........after1AdviceMethod111111111");
	}
	public void after2AdviceMethod(){
		System.out.println("..........after2AdviceMethod222222222");
	}
	public void beforeAdviceMethod(){
		System.out.println("beforeAdviceMethod..................");
	}
	public void exceptionAdviceMethod(Exception e){
		System.out.println("exceptionAdviceMethod................."+e);
	}
	public Object aroundAdviceMethod(ProceedingJoinPoint pjp){
		System.out.println("around-----------1");
		Object result=null;
		try {
			result=pjp.proceed();
		} catch (Throwable e) {
			throw new RuntimeException(e);
		}
		System.out.println("around-----------2");
		return result;
	}
}
4) 在核心配置文件中声明:context和aop的命名空间和xsd
5)创建目标bean和代理bean

    


    


6) 通过aop标签实现织入
                                           

    
        
        
        
        
        
    



    
        
        
        
    
7)测试
//		//创建spring上下文对象  关联核心配置文件
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("com/zhiyou/spring.xml");
StudentInterface studentProxy=(StudentInterface)context.getBean("stu2");
studentProxy.eatHao("黄焖鸡");
System.out.println();
studentProxy.gameCha("CS");
System.out.println();
studentProxy=(StudentInterface)context.getBean("stu");
studentProxy.eatHao("黄焖鸡");
System.out.println();
studentProxy.gameCha("CS");
context.close();
4、基于注解方式aop

增强类也就是代理类要用@AspectJ注解

1)创建核心配置文件引入context和aop的命名空间和xsd文件
2)在核心配置文件通过context标签指定扫描的实体类包
3)创建封装目标实体类并抽取接口
@Component
public class Teacher implements Serializable, TeacherInterface{
	@Value("1")
	private Integer tid;
	@Value("张老师")
	private String tname;
	@Value("3000")
	private Float tsalary;
    public void eatHao(String food){
		System.out.println("老师'"+tname+"'正在吃饭:'"+food+"'真香!");
	}
	public int teachHao(int a){
		System.out.println("老师'"+tname+"'正在授课::求"+a+"的三次方");
		//System.out.println(1/0);
		return (int)Math.pow(a, 3);
	}
	
	public void smokeCha(String name){
		System.out.println("老师'"+tname+"'正在吸烟:'"+name+"'吞云吐雾,注意身体!");
	}
    ...
}
//创建主流业务的实体类
@Component
public class Student implements Serializable, StudentInterface{
	@Value("韩梅梅")
	private String sname;
	@Value("1001")
	private Integer sid;
	@Value("99")
	private Float score;
	@Autowired
	private TeacherInterface teacher;
    	public int addHao(int a,int b){
		System.out.println("学生'"+sname+"'正在算术:"+a+"+"+b+"="+(a+b));
		return a+b;
	}
	public void eatHao(String food){
		System.out.println("学生'"+sname+"'正在吃饭:'"+food+"'真香!");
	}
	public void smokeCha(String name){
		System.out.println("学生'"+sname+"'正在吸烟:'"+name+"'吞云吐雾!");
	}
	public void sleepHao(){
		System.out.println("学生'"+sname+"'正在休息:劳逸结合!");
	}
	public void gameCha(String gname){
		System.out.println("学生'"+sname+"'正在玩游戏:玩物丧志!");
		
		return;
	}
    ...
}
4)创建增强实体类,并配置通知
@Component
@Aspect  //指定当前bean是通知bean
public class MyAdvice {
	 //通过注解@Pointcut定义切入点
	 @Pointcut("execution(* com.zhiyou100.day05.*.*Hao(..))")
	 public void haoPointCut() {}//方法名 即为切入点的id
	 //通过注解@Pointcut定义切入点
	 @Pointcut("execution(* com.zhiyou100.day05.*.*Cha(..))")
	 public void chaPointCut() {}//方法名 即为切入点的id
	 //通过注解@Pointcut定义切入点
	 @Pointcut("execution(* com.zhiyou100.day05.*.*(..))")
	 public void allPointCut() {}//方法名 即为切入点的id
	
	//@After(value="execution(* com.zhiyou100.day05.*.*Hao(..))")
	@After(value="haoPointCut()")
	public void after1AdviceMethod(JoinPoint jp){
		System.out.println("..........after1AdviceMethod111111111::"+jp.getSignature().getName());
	}
	
	
	//@AfterReturning(value="execution(* com.zhiyou100.day05.*.*Hao(..))",returning="result")
	@AfterReturning(value="haoPointCut()",returning="result")
	public void after2ReturningAdviceMethod(Object result){
		System.out.println("..........after2AdviceMethod222222222:::返回值是"+result);
	}
	
	//@Before(value="execution(* com.zhiyou100.day05.*.*Hao(..))")
	@Before(value="haoPointCut()")
	public void beforeAdviceMethod(JoinPoint jp){
		System.out.println("beforeAdviceMethod.................:::"+jp.getSignature().getName());
	}
	
	@AfterThrowing(value="allPointCut()",throwing="e")
	//@AfterThrowing(value="execution(* com.zhiyou100.day05.*.*(..))",throwing="e")
	public void exceptionAdviceMethod(Exception e){
		System.out.println("exceptionAdviceMethod................."+e);
	}
	
	//@Around(value="execution(* com.zhiyou100.day05.*.*Cha(..))")
	@Around(value="chaPointCut()")
	public Object aroundAdviceMethod(ProceedingJoinPoint pjp){
		System.out.println("around-----------1");
		Object result=null;
		try {
			result=pjp.proceed();
		} catch (Throwable e) {
			throw new RuntimeException(e);
		}
		System.out.println("around-----------2");
		return result;
	}  
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/459571.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号