首页
关于
Search
1
sql的注入原因和解决办法
134 阅读
2
SpringBoot整合腾讯云存储COS及基本使用,增删改查......
108 阅读
3
深究contains方法
100 阅读
4
多线程概述
73 阅读
5
学习的第一个注解@WebServlet - JavaWeb
73 阅读
默认分类
Java
C/C++
Mysql
JavaWeb
SpringBoot
算法
前端
Search
标签搜索
Spring
HTTP
Java
JavaWeb
IOC
mybatis
腾讯云
COS
云存储
CDN
achong
累计撰写
25
篇文章
累计收到
2
条评论
首页
栏目
默认分类
Java
C/C++
Mysql
JavaWeb
SpringBoot
算法
前端
页面
关于
搜索到
2
篇与
Spring
的结果
2023-03-03
Spring组件扫描原理 - 基础版
以下代码只是基本的组件扫描功能。全是Java的基础知识。类加载器、反射、注解、文件和文件夹操作、String的处理、集合。public static void main(String[] args) { Map<String, Object> beanMap = new HashMap<>(); // 1、需要扫描的目录 String packageName = "cn.qqwer.achong.IOC.bean"; // 2、将包名转换为路径格式 String packagePath = packageName.replaceAll("\\.","/"); // cn/qqwer/achong/IOC/bean // 3、通过系统加载器获取本地资源路径,返回一个URL对象 URL url = ClassLoader.getSystemClassLoader().getResource(packagePath); // 4、得到绝对路径 String path = url.getPath(); // 5、根据绝对路径得到file对象 File file = new File(path); // 6、获取路径下的所有类文件,获得数组 File[] files = file.listFiles(); // 7、开始逐个处理 Arrays.stream(files).forEach(f -> { // 8、拼接类文件的全包名 String className = packageName + "." +f.getName().split("\\.")[0]; // cn.qqwer.achong.IOC.bean.User try { // 9、根据类的全路径,获取类本身 Class<?> aClass = Class.forName(className); // 10、判断此类是否标记Component注解 if (aClass.isAnnotationPresent(Component.class)){ Component annotation = aClass.getAnnotation(Component.class); // 11、如果有注解、再继续判断@Component是否有值,即是否为bean设置ID String id = annotation.value(); if ("".equals(annotation.value())){ String simpleName = aClass.getSimpleName(); // 12、如果没为bean设置id,则将类文件名设置为bean的ID,类名首字母需转小写 if (!Character.isLowerCase(simpleName.charAt(0))){ id = new StringBuilder().append(Character.toLowerCase(simpleName.charAt(0))).append(simpleName.substring(1)).toString(); } } // 13、最好,将对象new出,并放到一个Map中。 Object obj = aClass.newInstance(); beanMap.put(id, obj); } } catch (Exception e) { throw new RuntimeException(e); } }); //输出map查看结果 System.out.println(beanMap); }
2023年03月03日
12 阅读
0 评论
0 点赞
2022-05-15
Spring - IOC
[TOC]一、IOC控制反转IOC就是对象创建的由谁来控制。正转:由程序员进行对象的创建和依赖注入称之为正传。就是程序员说了算。Student.stu = new Student( ); ===>程序员创建对象 stu.setName("张三"); ===>程序员进行赋值 stu.setAge(18); 反转:由Spring容器创建对象和依赖注入称为反转,将控制权从程序员手上夺走,由Spring管理,称之为反转。<bean id="stu" class="com.achong.entity.Student"> ===>Spring容器负责对象的创建 <property name="name" value="张三"> ===>Spring容器依赖注入值,也就是对对象赋值 <property name="age" value="20"> </bean>二、Bean管理Bean管理是指两个操作:Spring创建对象 和 Spring给对象的属性注入值。Bean管理有两种实现方式:基于XML配置文件 和 基于注解 。三、IOC接口IOC思想基于IOC容器完成,IOC容器底层就是对象工厂。Spring提供IOC容器实现的两种方式:BeanFactory和ApplicationContextBeanFactoryIOC容器的基本实现,是Spring内部使用的接口,一般不提供开发人员使用。ApplicationContextBeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员使用。两者的区别是:BeanFactory在加载配置文件的时候不会创建对象,在获取对象的时候采取创建对象;而ApplicationContext会在配置文件加载的时候就把对象创建好。四、 基于XML配置文件的Bean管理4.1.两种方式创建对象方式一:创建对象并注入值Bean标签是创建对象id是对象名称,名称唯一 ;class是对象的完全包名。propertory标签是为对象的属性注入值。若不需要注入则该标签不用写。name是属性名,value是属性值。注意:创建对象是调用无参构造方法,注入值是使用set方法。所以必须保证对象类里有这两种方法。<!--创建学生对象,在容器启动的时候--> <bean id="stu" class="com.achong.entity.Student"> <property name="name" value="张三"></property> <property name="age" value="18"></property> </bean> 取出对象 ClassPathXmlApplicationContext( )方法读取xml配置文件。 getBean( )方法取出创建好的对象。参数名为xml里对应Bean标签的id。 @Test public void TestSpringStudent(){ ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); Student stu = (Student) ac.getBean("stu"); System.out.println(stu ); }方式二:创建对象并注入值此方式调用的是带参的构造方法创建对象。使用 构造方法 的 参数名称 注入值。 <bean id="school" class="com.achong.entity.School"> <constructor-arg name="name" value="广东工程职业技术学院"></constructor-arg> <constructor-arg name="address" value="广东省清远市清城区"></constructor-arg> </bean>使用 构造方法 的 下标 注入值。 <bean id="stu" class="com.achong.entity3.Student"> <constructor-arg index="0" value="2005"></constructor-arg> <constructor-arg index="1" value="achong"></constructor-arg> <constructor-arg index="2" value="18"></constructor-arg> <constructor-arg index="3" ref="school"></constructor-arg> </bean>使用 构造方法 的 参数 的 顺序 注入值。<bean id="stu" class="com.achong.entity4.Student"> <constructor-arg value="2005"></constructor-arg> <constructor-arg value="achong"></constructor-arg> <constructor-arg value="18"></constructor-arg> <constructor-arg ref="school"></constructor-arg> </bean>4.2. 三种方式注入属性值简单类型注入 简单类型指的是八大基本数据类型。使用value属性注入。上面的例子就是简单类型注入。引用类型注入 引用类型指的是另一个对象。使用ref属性注入。集合类型注入 集合类型注入指数组,List,Map。 例如User类里包含另一个Address类。这时候就需要引用类型注入。代码实现 - 引用类型注入<!-- 创建学校对象--> <bean id="school" class="com.achong.entity2.School"> <property name="name" value="广东工程职业技术学院"></property> <property name="address" value="广东省清远市清城区中宿路"></property> </bean> <!-- 创建学生对象--> <bean id="stu" class="com.achong.entity2.Student"> <property name="name" value="achong"></property> <property name="age" value="20"></property> <property name="school" ref="school"></property> </bean>代码实现 - 集合类型注入<bean id="stu" class="com.achong.entity.Student"> <!--数组类型--> <property name="courses"> <array> <value>java</value> <value>Mysql</value> </array> </property> <!--List类型注入--> <property name="maps"> <list> <value>张三</value> <value>李四</value> </list> </property> <!--Map类型注入--> <property name="sets"> <set> <value>Mysql</value> <value>Redis</value> </set> </property> </bean>添加util约束空间,把list提取出来。提取出来的集合独立,可供多个Bean使用。 <util:list id="bookList"> <value>java</value> <value>Mysql</value> <value>Servlet</value> </util:list> <bean id="stu" class="com.achong.entity5.Student"> <property name="courseList" ref="bookList"></property> </bean>内部Bean写法 <bean id="stu" class="com.achong.entity2.Student"> <property name="name" value="achong"></property> <property name="age" value="20"></property> <property name="school"> <bean id="school" class="com.achong.entity2.School"> <property name="name" value="广东工程职业技术学院"></property> <property name="address" value="广东省清远市"></property> </bean> </property> </bean>4.3 属性值包含空值、特殊符号空值<property name="address"> <null/> </property>特殊符号 第二个中括号里面的内容为输入值。<property name="address"> <vlaue><[!CDATA[<<广东省>>]]></vlaue> </property>五、基于注解的Bean管理也称为DI(Dependency Injection),它是IOC的具体实现的技术。使用注解管理bean,可以省去在xml配置文件里写很多行代码,为xml减负。5.1 创建对象的注解@Component("指定的名称"):可以创建任意对象。@Controller("指定的名称"):专门用来创建控制器的对象(Servlet),这种对象可以接收用户的请求,可以返回处理结果给客户端。@Service("指定的名称"):专门用来创建业务逻辑层的对象,负责向下访问数据访问层,处理完成后的结果返回给界面层。Repository("指定的名称"):专门用来创建数据访问层的对象,负责数据库中的增删改查所有操作。四个注解的功能一模一样,可以混用,但是不建议,因为这本来就是用来区分三层结构的,value也可以不写,不写的话,创建的对象的名字按照驼峰命名法来命名。@Resource( ): 可以根据类型注入,根据名称注入。但是因为这个包是java拓展的而不是Spring提供的,所以不建议使用。5.2 属性值注入的注解值类型的注入@Value:用来给简单类型注入值。相当于构造函数赋值。引用类型的注入@Autowired:使用类型注入值,从整个Bean工厂中搜索同源类型的对象进行注入。@Autowired、@Quelifier:使用名称注入值,从整个Bean工厂中搜索相同名称的对象进行注入。5.3实现步骤添加包扫描只扫描指定包。指定包下面的,带有指定注解的类将被创建。<context:component-scan base-package="com.achong.entity"></context:component-scan>创建对象并注入@Component public class Student { @Value("2005") private int id; @Value("achong") private String name; @Value("18") private int age; @Autowired private School school; }添加测试类测试@Test public void Test01(){ ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); Student stu = (Student) ac.getBean("student"); System.out.println(stu); }注意:在有父子类的情况下,使用按类型注入,就意味着有多个可注入的对象,此时按照名称进行二次筛选,选中与被注入对象相同名称的对象进行注入。所以,如果有父子类,建议使用按名称注入。5.4 细节批量包扫描, 逗号隔开<context:component-scan base-package="com.achong.entity , com.achong.entity2 , com.achong.entity3"></context:component-scan>自定义包扫描规则<!-- use-default-filters 表示不使用默认扫描规则 include-filter 设置扫描哪些内容,这里表示 只扫描Controller这个注解 --> <context:component-scan base-package="com.achong" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- exclude-filter 设置哪些内容不扫描,这里表示Controller这个注解不会被扫描 --> <context:component-scan base-package="com.achong"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>5.4 配置类替代xml上面的方法需要使用到xml配置文件。但是,使用配置类可以替代配置文件。步骤: 创建一个空白类,添加相应注解@Configuration //标记为配置类,替代xml文件 @ComponentScan(basePackages = {"com.achong.entity4"}) //扫描路径 public class SpringConfig { }添加测试方法测试。注意:原本的 new AnnotationConfigApplicationContext(SpringConfig.class) 应改成new AnnotationConfigApplicationContext(SpringConfig.class); @Test public void Test04(){ ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class); Student student = (Student) ac.getBean("student"); System.out.println(student); }
2022年05月15日
44 阅读
0 评论
0 点赞