C C++最全Spring5架构,万字文章带你学习_spring5结构(1),2024年最新成功入职腾讯月薪45K

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

正转:由开发人员自己进行对象的创建和依赖的注入,开发人员自己管理,就是正转。

2),使用IOC的目的

为了降低耦合

3)IOC入门案例

2,IOC底层原理

1),xml解析,工厂模式,反射
2)图解IOC底层原理

传统方式:

4240640b79524479855961560b124b2f.png

工厂模式:

191feac52d964a08b3364ed05021f4fd.png

IOC模式:

7ca7606fce00452fad2160322cde0203.png

3.IOC接口(BeanFactory)

IOC基于容器完成,IOC容器的底层就是对象工厂

1),BeanFactory接口:

IOC容器的最基本实现,是spring内部的使用接口,不提倡给开发人员使用。

2),ApplicationContext接口:

是BeanFactory的子接口,提供比BeanFactory更强大的功能,一般为开发人员使用

3),两接口的区别

84a101f2318d40c882c6f143044e87c8.png

16259e0f328c48c48e2ec3d719d44368.png

因为我们在使用Spring框架时,一般都是配合网页使用,使用BeanFactory创建对象时,不会创建对象,而加载配置文件的时候,是在服务器启动的时候,使用tomcat,都是**将系统加载文件等费事非空间的事放在tomcat启动时完成,**以提供更好的用户体验,所以采用ApplicationContext接口

4),applicationContext的实现类

897a29a28edc4f58a804e9dfd48be5ba.png

4.IOC操作Bean管理(基于xml)

1),什么是bean管理:

**A,bean管理包括两个步骤:**Spring创建对象和Spring属性注入

5,bean管理的实现方式:

a,基于xml配置文件的实现方式
1.基于XML方式创建对象

378043c04f87444291ffb82732111625.png

id属性:给class类路径取个别名

class属性:创建对象类的全路径

XML方式创建默认对象默认使用空参构造器

2.基于XML方式的属性注入

(1),DI:依赖注入,就是注入属性。

DI与IOC的区别:DI是IOC的一种实现。

方式一:使用setter方式注入

A,使用setter方式注入,必须提供无参构造方法,必须实现setXXX()方法。

07fed5462c4d43cf9699e10c4732208a.png

B,在配置文件中配置对象创建,配置属性注入

c025222b127d499c8225cc08dc48f128.png

方式二:使用有参构造方法注入

ae0b00d793f7466aad0f626babea2f4a.png

facc6f16fd144960b97743a3c4c4d134.png

方式三:p名称空间注入:

第一步:

14b78cae321143bbb7ac6b4d42c9650c.png

第二步:

39775d07a3f24029ad0475fb5252ca54.png

3.注入空值和特殊字符

一,注入空值

92ce7153c0cd47a19874aff91546c83d.png

e305795af14d4c15bc5d781607c52171.png

二,注入特殊符号

a3c20105276242e5a046e09471036ddb.png

4,注入bean

1),注入外部bean

引入外部bean,用service调用Dao层,就是引入外部bean的过程。

e3b621b271cf432789b38365f2656f1e.png

2)注入内部bean 和 级联赋值

a1d1283ad2a04a71a5118e171f07e3da.png

级联赋值方式1:不需要dept的get方法。

efb08a391fd34d29a9bb18e2f05a65f2.png

级联赋值方式2:第二种方法需要创建dept的get方法。

d54ef5a1ad674089bda4e7c19baea6f7.png

5.注入集合属性

0),创建Stu类,User类

package com.yuge;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Stu {
    //数组类型
    private String course[];
    //List类型
    private List<String> name;
    //Map类型
    private Map<String,String> map;
    //Set类型
    private Set<String> set;
    //List类型中存入多个对象
    private List<User> userList;

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }

    public void setCourse(String[] course) {
        this.course = course;
    }

    public void setName(List<String> name) {
        this.name = name;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public void show(){
        System.out.println(Arrays.toString(course));
        System.out.println(name);
        System.out.println(map);
        System.out.println(set);
        System.out.println(userList);
    }
}

package com.yuge;

public class User {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void add(){
        System.out.println("add.......");
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

1).XML注入数组类型属性

2),XML注入List集合属性

3),XML注入Map集合属性

4),XML注入Map属性

5),在集合中注入对象属性:

<?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:m="http://www.springframework.org/schema/beans"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置Stu对象创建-->
    <bean id="stu" class="com.yuge.Stu">
        <!--注入数组属性-->
        <property name="course">
            <array>
                <value>javaSe</value>
                <value>Mysql</value>
            </array>
        </property>
        <!--注入List对象-->
        <property name="name">
            <list>
                <value>武巴</value>
                <value>巴巴</value>
            </list>
        </property>
        <!--注入Map对象-->
        <property name="map">
            <map>
                <entry key="JAVASE" value="javase"></entry>
                <entry key="SPRING" value="Spring"></entry>
            </map>
        </property>
        <!--注入Set对象-->
        <property name="set">
            <set>
                <value>张三</value>
                <value>小三</value>
            </set>
        </property>
        <!--在list中注入对象属性-->
        <property name="userList">
            <list>
                <ref bean="user1"></ref>
                <bean id="user1=2" class="com.yuge.User">
                    <property name="name" value="李华"></property>
                </bean>
            </list>
        </property>
    </bean>
    <bean id="user1" class="com.yuge.User">
        <property name="name" value="李烨"></property>
    </bean>


</beans>

6),创建测试类

package com.yuge.test;

import com.yuge.Stu;
import com.yuge.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.applet.AppletContext;

public class Tset {

    @Test
    public void testAdd(){
        //加载配置文件
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("bean2.xml");
        //创建对象
        Stu stu = (Stu) applicationContext.getBean("stu");
        stu.show();
    }
}

7),输出结果

b9d663d9b29f4bf28a52359c6fc06613.png

8).将集合向上抽取为所有bean的公共集合

第一步:引入新的名称空间:

7eb38d078cd94ce491518226572eb0ae.png

第二步:使用util标签完成list集合注入的向上抽取

创建新的Book类测试向上抽取注入list

package com.yuge;

import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;

import java.util.List;

public class Book {
    private List<String> bookList;

    public void setBookList(List<String> bookList) {
        this.bookList = bookList;
    }

    public void test(){
        System.out.println(bookList);
    }
}

配置XML文件抽取注入list的方法:

<?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:p="http://www.springframework.org/schema/p"
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation=
                            "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
    <util:list id="list">
        <value>java从入门到入土</value>
        <value>python从入门到入狱</value>
    </util:list>
    <bean id="book" class="com.yuge.Book">
        <property name="bookList" ref="list"></property>
    </bean>
</beans>

运行结果:抽取成功

83e931d8f9e54fae9e6bf87718f5b7d6.png

抽取之前的样子:

893f605ebfd44ae8ae316f358aa9e639.png

抽取之后的样子:

e44c488e75164872af980fefa53c6d63.png

还可以抽取更多的对象。

3d8c1ffd30a845919b14d966d4993465.png

7d378da0e2dd4d4ab80ba0c53ba59211.png

6,Spring中的两种bean

1)普通bean:XML中定义什么类型就返回什么类型

2),工厂bean:XML中定义一个类型,可以返回其他类型

第一步:创建类作为工厂bean,实现FactoryBean的接口

第二步:实现接口里的方法,在实现的方法中定义返回的bean类型

package com.yuge.factoryBean;

import com.yuge.Stu;
import org.springframework.beans.factory.FactoryBean;

public class Mybean implements FactoryBean<Stu> {
    @Override
    public Stu getObject() throws Exception {
        Stu stu = new Stu();
        return stu;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}

第三步:配置XML文件

    <bean id="myBean" class="com.yuge.factoryBean.Mybean">
    </bean>

测试:

    @Test
    public void testMyBean(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        Stu stu = context.getBean("myBean",Stu.class);
        System.out.println(stu);
    }

结果:

162edb242f5042d095b90653af6b1b8a.png

7,bean的作用域:

8de13ad4cc2c46268d201847fcc0ca52.png

在XML中配置bean时单实例还是多实例:

48316bb8ab7a49ad8668408e68121b2b.png

bf8d370dd7914834a9dc42bc5b9e9593.png

341e907edaf34931a520dba6c4c0bc2b.png

8,XML的自动装配

335bded283544e4ea16fa09cd093e8d7.png

自动装配:根据指定的装配规则,(属性名称或者属性类型),Spring自动将匹配的属性值填入。

演示自动自动装配:

1,根据名称装配

4dbf6458f2ac4a039599698e195d3c4e.png

2,根据属性类型装配

7ff0e97f4a4e48cebc01945937598c87.png

9,引入外部属性管理

1b03f5ce4d454b62b06f8b19c98523d6.png

a522022b892e46a69a5e272d00336444.png

bc0269a7824a418497495bc6e9b6921e.png

4.IOC操作Bean(基于注解)

DI(依赖注入),DI时IOC的具体实现

1,spring针对创建对象提供的注解

第一步引入依赖:

567e48a57fab46199629a6202d963ae8.png

第二步:开启组件扫描

c9966bfbea904caeb15450dc03043dbf.png

第三步:创建类,在类上添加上注解

1,@Component,都可以使用改注解创建对象

2,@Service,一般用于业务逻辑层,或者service层,负责向下访问数据访问层,将结果返回给界面层

3,@Controller,一般用于Web层,界面层,专门用于处理用户请求,将处理的结果返回给客户端

4,@Repository,一般用于Dao层,数据访问层,专门用来创建数据访问层的对象,负责管理数据的所有增删改查操作。

*上面的资格注解,功能都一样,只是将每个注解用于不同层便于开发人员区别。

2,开启组件扫面配置的细节配置

8bc4efb9887d4d2b977091a2b1aad163.png

793789032ae24ed8ad187203fea2c474.png

52277a95418f402c862dd3acc0d08bd6.png

3,使用注解出入属性

1),@Autowired:根据属性类型自动注入(引用类型注入)

第一步:使用注解在各个类中创建对象。

第二步:定义对象属性。在属性上面添加注解。不需要set方法。

6255901c6d31407a8cb6b1a670da8bf9.png

2),@Qualifier:根据属性名注入(引用类型 注入)

qualifier注解和Autowired注解需要配合在一起使用

770277417e8342a0a092c0c23405dcfd.png

3),@Resource:可以根据属性名和属性类型注入(引用类型注入)

f8b4a06ddfb34498a5c37231740c1726.png

*************以上三种是注入对象,不是普通类型**************

4),@Value:注入普通类型

c928177486bc4fad96211ddea4c743d7.png 4,完全注解开发

1),创建配置类,替代XML配置文件

298e8698e7f94ea1a3165e7aa52c493f.png

2),编写测试类

40477ea1ed5f46a7880ddd9a886db7f0.png

5,为Spring指定多个xml文件

拆分文件的策略:

6,Spring配置文件的整和

单个整合

批量整和

 

三,Aop

面向切面(将公共代码抽取出来的,这个公共的部分就是切面),将公共的代码提取出来,在各个模块需要使用该功能时,引入该功能,同时可以在功能需要加强时,不修改其他代码,只需要修改切面上的代码,就可以进行功能加强。

1,什么是AOP

对业务的各个逻辑进行隔离,从而使业务之间的逻辑耦合性降低,提高代码的可重用性,提高开发效率。

b1ffe98583d2435aa479e4abeed2698a.png

2,AOP的底层原理

1,AOP底层使用动态代理

动态代理:某个方法在执行时,动态的切入了其他功能。(如在实现业务功能时,将日志打印切入到业务功能中,就是动态代理的一种形式)

1,有接口的动态代理,使用JDK的动态代理

创建接口的实现类的代理对象,增强类的方法

ec155db6e48645879ab4feeb09f70527.png

2,无接口的动态代理,使用CGLIB动态代理

创建子类的代理对象,增强类的方法

025a308d8288483dac9e9074294405b5.png

2,使用JDK的动态代理

使用proxy类实现动态代理

15607ac9a6c64c46b879e9b97e05ee77.png

4a2667ffd1a04fd9bc5cf8e14bb156c2.png

代码实现:

1,创建接口:

package com.JDK动态代理;

public interface UserDao {
    public int add(int a,int b);

    public String update(String id);
}

2,创建实现类

package com.JDK动态代理;

public class UserDaoImpl implements UserDao{
    @Override
    public int add(int a, int b) {
        return a+b;
    }

    @Override
    public String update(String id) {
        return id;
    }
}

3,使用proxy类创建接口的动态代理对象

package com.JDK动态代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.security.PublicKey;
import java.security.UnresolvedPermission;
import java.util.Arrays;

public class JDKProxy  {
    public static void main(String[] args) {
        Class[] interfaces = {UserDao.class};
        UserDao dao = (UserDao)Proxy.newProxyInstance(UserDaoProxy.class.getClassLoader(), interfaces, new UserDaoProxy(new UserDaoImpl()));
        int res = dao.add(1, 2);
        System.out.println(res);
    }
}

class UserDaoProxy implements InvocationHandler{

    //需要将待增强功能的类的对象传递到代理类中,并通过构造方法,代理类的构造方法将其实例化
    //通过UserDaoProxy创建UserDaoImpl的代理对象
    private Object obj;
    public UserDaoProxy(Object obj){
        this.obj = obj;
    }

    @Override
    /**
     *增加逻辑写在这个方法内
     * @ proxy:代理对象
     * @ method:需要增强的方法
     * @ args:要增强功能的方法需要的参数
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法之前
        System.out.println("方法之前执行。。。"+method.getName()+"传递的参数:"+ Arrays.toString(args));
        //被增强方法执行
        Object res = method.invoke(obj, args);
        //方法之后执行
        System.out.println("方法之后执行。。。"+obj);
        return res;
    }
}

0e13db1a874941169d12d4865b556b6d.png

3,AOP中的相关术语

1,连接点:那些方法可以被增强,那些方法就叫连接点。

2,切入点:世界真正被增强的方法就叫切入点。

3,通知(增强):实际被增强的逻辑部分就叫通知或者增强。

通知有多种类型:

7b1cf037816a4fcc884ffa7fad208f26.png

4,切面:把通知应用到切入点的动作就叫做切面

4,AOP的操作准备

1,Spring框架一般都是基于AspectJ实现AOP操作

AspectJ框架

:强大的面向切面的实现,不是Spring框架的一部分,独立于AOP的框架,一般将Spring和AOP框架一起使用进行AOP操作。

2,基于AspectJ实现AOP操作

(1),基于XML配置文件的AOP操作

(2),基于注解方式实现(使用)

3,在项目的过程中,引入AOP相关的依赖。

420025aaf2c547f2b6c7540423b76334.png

4,切入点表达式

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

(2),语法结构:

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

简化后:execution(返回值类型,方法声明参数(…))

…代表任意参数,如果在路径中出现,代表本路径及其所有的子路径

*代表通配符

举例1:execution((权限修饰可以省略) * com.yuge.UserDaoImpl.add(…));

加强com.yuge.UserDaoImpl的add()方法,传入的参数用…表示,权限修饰符用*,返回值类型省略。

举例2:execution((权限修饰可以省略) * com.yuge.UserDaoImpl.*(…));    对类中的所有方法加强。

举例3:execution((权限修饰可以省略) * com.yuge.*.*(…));    对包中所有类的所有方法加强

5,AOP操作(AspectJ注解)

1,创建一个类,在类中定义方法,使用注解在类中增强该方法。

package com.AOP注解方式;

public class User {
    public void add(){
        System.out.println("add...................");
    }
}

2,创建一个增强类,编写增强逻辑

package com.AOP注解方式;

//增强类
public class UserProxy {

    //前置通知
    public void before(){
        System.out.println("before.............");
    }
}

3,进行通知的配置

(0)、引入名称空间

51228e6efe224a0ba26d93fdaf935540.png

(1),在spring的配置文件中,开启注解扫描

    <!--开启注解扫描-->
    <context:component-scan base-package="com.AOP注解方式"></context:component-scan>

(2),使用注解创建User对象和UserProxy对象。

6c396c7146344ff789df5f521ed4d988.png

(3),在增强类上面添加@Aspect注解

eb29c593aa7e43688f2b5dc79dbff87f.png

(4),在spring配置文件中开启生成代理对象。

    <!--开启AspectJ生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

(5),配置不同类型 的通知

a,在增强类方法上面,添加通知类型。使用切入点表达式配置

package com.AOP注解方式;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

//增强类
@Component
@Aspect //生成代理对象
public class UserProxy {

    //前置通知,添加了Before注解,则就会在add()方法之前执行before方法。
    @Before("execution(* com.AOP注解方式.User.add(..))")
    public void before(){
        System.out.println("before.............");
    }

    //在方法执行之后执行
    @After("execution(* com.AOP注解方式.User.add(..))")
    public void after(){
        System.out.println("after.............");
    }

    //在方法存在异常时执行
    @AfterThrowing("execution(* com.AOP注解方式.User.add(..))")
    public void afterThrowing(){
        System.out.println("afterThrowing.............");
    }

    //在方法返回之后执行
    @AfterReturning("execution(* com.AOP注解方式.User.add(..))")
    public void afterReturning(){
        System.out.println("afterReturning.............");
    }

    //添加环绕方法,在方法执行前后都执行
    @Around("execution(* com.AOP注解方式.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕之前.............");

        //被增强的方法执行
        proceedingJoinPoint.proceed();

        System.out.println("环绕之后..............");
    }
}

package com.AOP注解方式;

import org.springframework.stereotype.Component;

@Component
public class User {
    public void add(){
        System.out.println("add...................");
    }
}

package com.AOP注解方式;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    @org.junit.Test
    public void testAdd(){
        //加载上下文配置,读取xml配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
        //获取代理对象
        User user = (User)context.getBean("user");

        user.add();
    }
}

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       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/context
http://www.springframework.org/schema/context/spring-context.xsd

                http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
    <!--开启注解扫描-->
    <context:component-scan base-package="com.AOP注解方式"></context:component-scan>
    <!--开启AspectJ生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    <bean id="user" class="com.AOP注解方式.User"></bean>
</beans>

运行结果:

9a0b5f8910ff4dbb83841729d790386a.png

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

/www.springframework.org/schema/context"
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/context

http://www.springframework.org/schema/context/spring-context.xsd

            http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop.xsd
">

<context:component-scan base-package=“com.AOP注解方式”></context:component-scan>

aop:aspectj-autoproxy</aop:aspectj-autoproxy>

<bean id="user" class="com.AOP注解方式.User"></bean>
```

运行结果:

9a0b5f8910ff4dbb83841729d790386a.png

[外链图片转存中…(img-49ymfXAF-1715697500114)]
[外链图片转存中…(img-z0OfERRW-1715697500114)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值