跳到主要内容
SUN / 笔记
← 全部文章

Java语言基础

局部变量

  • 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。

修饰符

像其他语言一样,Java可以使用修饰符来修饰类中方法和属性。主要有两类修饰符:

  • 访问控制修饰符 : default, public , protected, private
  • 非访问控制修饰符 : final, abstract, static, synchronized

Java注解(Annotation)

关键字

transient

变量修饰符,用于在序列化过程中忽略该变量,在反序列化过程中transient变量将被设为初始值。

instanceof

二元操作符,用于判断左侧对象是否是右侧类的实例

java
public static void displayObjectClass(Object o){
	if(o instanceof Vector)
		sout();
    else if(o instanceof ArrayList)
        sout();
    else
        sout();
}
volatile

volatile 关键字保证变量的可见性和有序性,但不保证原子性:

  • 可见性:一个线程修改了 volatile 变量的值,其他线程能立即看到最新值
  • 有序性:禁止 JVM 对 volatile 变量相关的指令进行重排序
  • 不保证原子性:count++ 这样的复合操作仍然不是线程安全的,需要用 AtomicInteger 或 synchronized
java
// 典型用法:双重检查锁定单例
private static volatile Singleton instance;

参数传递

三种参数传递方法:

  • 传值调用
  • 传引用调用
  • 传共享对象调用

Java的参数传递本质是传共享对象调用,也可以理解为把对象地址作为值进行传值调用。传参过程中会发生求值、拷贝、传递的过程。而这个过程的主体是对象的内存地址。

Java的参数传递不是引用调用,传值保证作为参数传入的对象在返回是依然指向原对象,但是函数内部可以对该地址指向对象的内部进行修改。

Spring

狭义的Spring指Spring框架(Spring FrameWork)

广义的Spring指Spring生态:

  • 分布式微服务 Microservices
  • 响应式编程 Reactive
  • 云端技术 cloud
  • Spring MVC Web Apps
  • 无服务器编程 Serverless
  • 事件驱动 Event Driven

Spring的体系结构

1. Data Access/Integration(数据访问/集成)

数据访问/集成层包括 JDBC、ORM、OXM、JMS 和 Transactions 模块,具体介绍如下。

  • JDBC 模块:提供了一个 JDBC 的抽象层,大幅度减少了在开发过程中对数据库操作的编码。
  • ORM 模块:对流行的对象关系映射 API,包括 JPA、JDO、Hibernate 和 iBatis 提供了的集成层。
  • OXM 模块:提供了一个支持对象/XML 映射的抽象层实现,如 JAXB、Castor、XMLBeans、JiBX 和 XStream。
  • JMS 模块:指 Java 消息服务,包含的功能为生产和消费的信息。
  • Transactions 事务模块:支持编程和声明式事务管理实现特殊接口类,并为所有的 POJO。

2. Web 模块

Spring 的 Web 层包括 Web、Servlet、Struts 和 Portlet 组件,具体介绍如下。

  • Web 模块:提供了基本的 Web 开发集成特性,例如多文件上传功能、使用的 Servlet 监听器的 IoC 容器初始化以及 Web 应用上下文。
  • Servlet模块:包括 Spring 模型—视图—控制器(MVC)实现 Web 应用程序。
  • Struts 模块:包含支持类内的 Spring 应用程序,集成了经典的 Struts Web 层。
  • Portlet 模块:提供了在 Portlet 环境中使用 MV C实现,类似 Web-Servlet 模块的功能。

3. Core Container(核心容器)

Spring 的核心容器是其他模块建立的基础,由 Beans 模块、Core 核心模块、Context 上下文模块和 Expression Language 表达式语言模块组成,具体介绍如下。

  • Beans 模块:提供了 BeanFactory,是工厂模式的经典实现,Spring 将管理对象称为 Bean。
  • Core 核心模块:提供了 Spring 框架的基本组成部分,包括 IoC 和 DI 功能。
  • Context 上下文模块:建立在核心和 Beans 模块的基础之上,它是访问定义和配置任何对象的媒介。ApplicationContext 接口是上下文模块的焦点。
  • Expression Language 模块:是运行时查询和操作对象图的强大的表达式语言。

4. 其他模块

Spring的其他模块还有 AOP、Aspects、Instrumentation 以及 Test 模块,具体介绍如下。

  • AOP 模块:提供了面向切面编程实现,允许定义方法拦截器和切入点,将代码按照功能进行分离,以降低耦合性。
  • Aspects 模块:提供与 AspectJ 的集成,是一个功能强大且成熟的面向切面编程(AOP)框架。
  • Instrumentation 模块:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用。
  • Test 模块:支持 Spring 组件,使用 JUnit 或 TestNG 框架的测试。

Spring IoC 控制反转

Inverse of Control,一种设计理念,是现代程序设计遵循的标准,是宏观目标。

DI(Dependency Injection)依赖注入,Java中关于IoC的具体技术实现。

DI在Java中通过反射技术实现对象注入(Injection)

由代理人来创建和管理对象,消费者通过代理人来获取对象。

IoC的目的是降低对象之间的直接耦合

image-20210616161336580

bean对象的生命周期

image-20210619231114391

image-20210620180248110

pom.xml配置文件

xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.imooc.spring</groupId>
    <artifactId>ioc</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>15</maven.compiler.source>
        <maven.compiler.target>15</maven.compiler.target>
    </properties>

    <repositories>
        <repository>
            <id>aliyun</id>
            <name>aliyun</name>
            <url>https://maven.aliyun.com/repository/public</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.8</version>
        </dependency>
    </dependencies>
</project>

三种配置方式

基于XML配置

applicationContext.xml

xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
	<bean id="apple2" class="com.imooc.spring.ioc.entity.Apple">	
	<!-- 没有constructor-arg则代表调用默认构造方法实例化-->
        <constructor-arg name="title" value="红富士"/>
        <constructor-arg name="origin" value="欧洲"/>
        <constructor-arg name="color" value="红色"/>
        <constructor-arg name="price" value="19.8"/>
    </bean>

    <bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
        <!-- IoC容器自动利用反射机制运行时调用setXXX方法为属性赋值-->
        <property name="title" value="红富士"/>
        <property name="origin" value="欧洲"/>
        <property name="color" value="红色"/>
        <property name="price" value="19.8"/>
    </bean>


    <bean id="lily" class="com.imooc.spring.ioc.entity.Child">
        <property name="name" value="莉莉"/>
        <!-- 利用ref setter实现对象参数注入-->
        <property name="apple" ref="sweetApple"/>
    </bean>

    <bean id="andy" class="com.imooc.spring.ioc.entity.Child">
        <!-- 利用构造方法注入对象-->
        <constructor-arg name="name" value="安迪"/>
        <constructor-arg name="apple" ref="sourApple"/>
    </bean>
    
	<!--    利用静态工厂获取对象-->
    <bean id="apple4" class="com.imooc.spring.ioc.factory.AppleStaticFactory"
          factory-method="createSweetApple"/>

	<!--    利用工厂实例方法创建对象-->
    <bean id="factoryInstance" class="com.imooc.spring.ioc.factory.AppleFactoryInstance"/>
    <bean id="apple5" factory-bean="factoryInstance" factory-method="createSweetApple"/>
    
    
</beans>

静态工厂的好处,可以在创建函数中进行一些其他的需要的操作,如日志输出等。

随着Spring发展工厂模式也较少使用了

constructor-arg和property区别

  • constructor-arg调用构造函数创建实例
  • property调用setXXX方法为属性赋值

bean标签中id和name

相同点

  • bean id 和 name都是设置对象在IoC容器中唯一标识
  • 两者在同一个配置文件中都不允许重复
  • 两者允许在多个配置文件中出现重复,新对象覆盖旧对象

不同点

  • id要求更为严格,一次只能定义一个对象标识(推荐)
  • name更为宽松,一次允许定义多个对象标识
  • id与name的命名要求有意义,按驼峰命名书写

一般只使用id

java
//创建IoC容器并根据配置文件创建对象
ApplicationContext context = new ClassPathXmlApplcationContext("classpath:applicationContext.xml");

image-20210617110219662

classpath指编译后的运行目录target下的classes

image-20210617110326009

注入集合对象
xml
<bean id="" class="">
    <propertyname="someList">
        <list>
            <value>123</value>
            <ref bean="beanId"></ref>
        </list>
    </propertyname>
</bean>

<bean id="" class="">
    <propertyname="someSet">
        <set>
            <value>123</value>
            <ref bean="beanId"></ref>
        </set>
    </propertyname>
</bean>

<bean id="" class="">
    <propertyname="someMap">
        <map>
            <entry key="k1" value="v1"></entry>
            <entry key="k2" value-ref="beanId"></entry>
        </map>
    </propertyname>
</bean>

<!--Properties的键和值必须是字符串-->
<bean id="" class="">
    <propertyname="someProperties">
        <props>
            <prop key="k1">v1</entry>
            <prop key="k2">v2</entry>
        </props>
    </propertyname>
</bean>
查看容器内对象
java
String[] beanNames = context.getBeanDefinitionNames();
for(String beanName:beanNames){
    System.out.println(beanName);
    System.out.println("type: " + context.getBean(beanName).getClass().getName());
    System.out.println("context: " + context.getBean(beanName).toString());
}
bean scope属性
  • bean scope属性用于决定对象何时被创建与作用范围
  • bean scope配置将影响容器内对象的数量
  • bean scope默认值singleton(单例),指全局共享同 一个对象实例

scope属性清单

singleton:单例模式(默认模式)

prototype:多例,每次使用时创建一个实例

image-20210619225106432

上图情况中,左侧三个bean注入的userDao都是同一个实例。

singleton在容器是单例多线程的,但是存在线程安全风险。

image-20210619225349281

image-20210619225509625

基于注解配置

注解:Annotation

组件类型注解

xml
<!--XML配置开启组件扫描,才能使用注解-->
<?xml version="1.0" encoding="UTF-8"?>
<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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.imooc"/>

</beans>
  • @Component:组件注解,通过注解,被该注解描述的类将被IoC容器管理并实例化
  • @Controller:语义注解,说明当前类是MVC应用中的控制器类
  • @Service:语义注解,说明当前类是Service业务服务类
  • @Repository:语义注解,说明当前类用于业务持久层,通常描述对应Dao类

自动装配注解

image-20210620132735407

@Autowired 按类型注入,不推荐使用

java
package com.imooc.spring.ioc.service;

import com.imooc.spring.ioc.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    public UserService() {
        System.out.println("creating UserService:" + this);
    }

    @Autowired
    //Spring IoC容器会自动通过反射技术将属性private修饰符改为public,直接进行赋值
    //不再执行set方法
    private UserDao udao;

    public UserDao getUdao() {
        return udao;
    }

    @Autowired
    //如果装配注解放在set方法上,则自动按类型/名称对set方法参数进行注入
    public void setUdao(UserDao udao) {
        System.out.println("setUdao:" + udao);
        this.udao = udao;
    }
}

@Resource

  1. 设置name属性,则按name在IoC容器中将bean注入
  2. 未设置name属性
    1. 以属性名作为bean name在IoC容器中匹配bean,如有匹配则注入
    2. 按属性名未匹配,则按类型进行匹配,同@Autowired,需加入@Primary解决类型冲突

元数据注解

image-20210620134112035

  1. 创建配置文件
  2. 在xml中加载配置文件
  3. 在Value注解中加载键值对

注解需要修改源代码,但是配置方便,避开了繁琐的xml文件配置

基于Java Config代码配置

  • 完全摆脱XML的束缚,使用独立java类管理对象与依赖
  • 注解配置相对分散,利用Java Config可对配置集中管理
  • 可以在编译时进行依赖检查,不容易出错

image-20210620140742745

java
package com.imooc.spring.ioc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringApplication {
    public static void main(String[] args) {
        //基于Java Config配置IoC容器的初始化
        ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);

        String[] ids = context.getBeanDefinitionNames();
        for(String id : ids){
            System.out.println(id + ":" + context.getBean(id));
        }
    }
}

Spring Test

(插图未导入)

Spring AOP 面向切面编程

Aspect Oriented Programming

Spring AOP 是基于 AOP 编程模式的一个框架,它的使用有效减少了系统间的重复代码,达到了模块间的松耦合目的。

名称 说明
Joinpoint(连接点) 指那些被拦截到的点,在 Spring 中,可以被动态代理拦截目标类的方法。
Pointcut(切入点) 指要对哪些 Joinpoint 进行拦截,即被拦截的连接点。
Advice(通知) 指拦截到 Joinpoint 之后要做的事情,即对切入点增强的内容。
Target(目标) 指代理的目标对象。
Weaving(植入) 指把增强代码应用到目标上,生成代理对象的过程。
Proxy(代理) 指生成的代理对象。
Aspect(切面) 切入点和通知的结合。

相关文章

如何启动 & 基本运行 →C++面向对象 →day02——面向对象高级 →