spring6之容器:IOC
创始人
2024-12-26 19:33:32
0

 容器:IOC

控制反转(Ioc)

                                                                

IoC容器在Spring的实现

Spring 的 IoC 容器就是 IoC思想的一个落地的产品实现。IoC容器中管理的组件也叫做 bean。在创建 bean 之前,首先需要创建IoC 容器。Spring 提供了IoC 容器的两种实现方式:

**①BeanFactory**

这是 IoC 容器的基本实现,是 Spring 内部使用的接口。面向 Spring 本身,不提供给开发人员使用。

**②ApplicationContext**

BeanFactory 的子接口,提供了更多高级特性。面向 Spring 的使用者,几乎所有场合都使用 ApplicationContext 而不是底层的 BeanFactory。

**③ApplicationContext的主要实现类**

获取bean的三种方式:

package com.zzq.spring6.iocxml;  import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class TestUser {     public static void main(String[] args) {         ApplicationContext context=new                 ClassPathXmlApplicationContext("bean.xml");         //根据id获取bean         User user1=(User) context.getBean("user1");         System.out.println(""+user1);         //根据类型获取bean         User user2=context.getBean(User.class);         System.out.println(""+user2);         //根据id和类型获取bean         User user3=context.getBean("user",User.class);         System.out.println(""+user3);     } } 

如果组件类实现了接口,根据接口类型可以获取 bean 吗?

> 可以,前提是bean唯一

如果一个接口有多个实现类,这些实现类都配置了 bean,根据接口类型可以获取 bean 吗?

> 不行,因为bean不唯一
依赖注入:

1、类有属性,创建对象过程中,向属性设置值

第一种方式:基于set方法完成

package com.zzq.spring6.iocxml.di;  import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class TestBook {     @Test     public void testSetter(){         ApplicationContext context=new                 ClassPathXmlApplicationContext("bean-di.xml");         Book book = context.getBean("book", Book.class);         System.out.println(book);     } } 

 book.java

package com.zzq.spring6.iocxml.di;  public class Book {     private String bname;     private  String author;      @Override     public String toString() {         return "Book{" +                 "bname='" + bname + '\'' +                 ", author='" + author + '\'' +                 '}';     }      public String getBname() {         return bname;     }      public void setBname(String bname) {         this.bname = bname;     }      public String getAuthor() {         return author;     }      public void setAuthor(String author) {         this.author = author;     }      public Book(String bname, String author) {         this.bname = bname;         this.author = author;     }      public Book() {     } } 

bean-di.xml

              

第二种方式:基于构造器完成

                                                                
package com.zzq.spring6.iocxml.di;  import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class TestBook {        @Test     public void testConstructor(){         ApplicationContext context=new                 ClassPathXmlApplicationContext("bean-di.xml");         Book book = context.getBean("bookCon", Book.class);         System.out.println(book);     } } 

特殊值处理

##### ①字面量赋值

> 什么是字面量?
>
> int a = 10;
>
> 声明一个变量a,初始化为10,此时a就不代表字母a了,而是作为一个变量的名字。当我们引用a的时候,我们实际上拿到的值是10。
>
> 而如果a是带引号的:'a',那么它现在不是一个变量,它就是代表a这个字母本身,这就是字面量。所以字面量没有引申含义,就是我们看到的这个数据本身。

```xml


```

##### ②null值

```xml

   

```

> 注意:
>
> ```xml
>
> ```
>
> 以上写法,为name所赋的值是字符串null

##### ③xml实体

```xml



```

##### ④CDATA节

```xml

   
   
   
   
   

```


为对象类型属性赋值:

第一种方式:

引入外部bean

1、创建两个类对象:dept和emp

2、在emp的bean标签里面,使用property引入dept的bean

package com.zzq.spring6.iocxml.ditest; //部门类 public class Dept {      private  String dname;      public void setDname(String dname) {         this.dname = dname;     }      public  void info(){         System.out.println("部门名称:"+dname);     } } 
package com.zzq.spring6.iocxml.ditest; //员工类 public class Emp {     //对象类型属性:员工属于某个部门     private Dept dept;     private  String ename;     private Integer age;      public Dept getDept() {         return dept;     }     public  void  work(){         System.out.println(ename+"emp work...."+age);         dept.info();     }     public void setDept(Dept dept) {         this.dept = dept;     }      public String getEname() {         return ename;     }      public void setEname(String ename) {         this.ename = ename;     }      public Integer getAge() {         return age;     }      public void setAge(Integer age) {         this.age = age;     }   } 
package com.zzq.spring6.iocxml.ditest;  import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class TestEmp {     public static void main(String[] args) {       ApplicationContext context=new             ClassPathXmlApplicationContext("bean-ditest.xml");         Emp emp = context.getBean("emp", Emp.class);         emp.work();     } }
                                                                    

第二种方式:

内部bean的注入

                                                                                                           

 第三种方式:

级联赋值

                                                                 

注入数组类型的属性 

package com.zzq.spring6.iocxml.ditest;  import java.lang.reflect.Array; import java.util.Arrays;  //员工类 public class Emp {     //对象类型属性:员工属于某个部门     private Dept dept;     private String ename;     private Integer age;     private String[] loves;      public void work() {         System.out.println(ename + "emp work...." + age);         dept.info();         System.out.println(Arrays.toString(loves));     }     public void setLoves(String[] loves) {         this.loves = loves;     }      public Dept getDept() {         return dept;     }     public void setDept(Dept dept) {         this.dept = dept;     }      public String getEname() {         return ename;     }      public void setEname(String ename) {         this.ename = ename;     }      public Integer getAge() {         return age;     }      public void setAge(Integer age) {         this.age = age;     }   } 
                                                                                                               睡觉                 听歌                 追剧                            

为集合类型属性赋值

List集合属性的注入

                                                                                                                               
package com.zzq.spring6.iocxml.ditest;  import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class TestDept {     public static void main(String[] args) {       ApplicationContext context=new             ClassPathXmlApplicationContext("bean-dilist.xml");        Dept dept = context.getBean("dept", Dept.class);         dept.info();     } }
package com.zzq.spring6.iocxml.ditest;  import java.util.List;  //部门类 public class Dept { //一个部门有很多员工     private List empList;      public List getEmpList() {         return empList;     }      public void setEmpList(List empList) {         this.empList = empList;     }      public String getDname() {         return dname;     }      private  String dname;      public void setDname(String dname) {         this.dname = dname;     }      public  void info(){         System.out.println("部门名称:"+dname);         for (Emp emp:empList) {             System.out.println(emp.getEname());         }     } } 

map集合属性的注入

Student类

package com.zzq.spring6.iocxml.dimap;  import java.util.Map;  public class Student {     private String sid;     private String name;     private Map teacherMap;      public void run() {         System.out.println("学生编号: " + sid +                 "学生名称: " + name);         System.out.println(teacherMap);     }      @Override     public String toString() {         return "Student{" +                 "sid='" + sid + '\'' +                 ", name='" + name + '\'' +                 ", teacherMap=" + teacherMap +                 '}';     }      public Map getTeacherMap() {         return teacherMap;     }      public void setTeacherMap(Map teacherMap) {         this.teacherMap = teacherMap;     }      public String getSid() {         return sid;     }      public void setSid(String sid) {         this.sid = sid;     }      public String getName() {         return name;     }      public void setName(String name) {         this.name = name;     } } 

Teacher类

package com.zzq.spring6.iocxml.dimap;  public class Teacher {     private String teacherId;     private String teacherName;      @Override     public String toString() {         return "Teacher{" +                 "teacherId='" + teacherId + '\'' +                 ", teacherName='" + teacherName + '\'' +                 '}';     }      public String getTeacherId() {         return teacherId;     }      public void setTeacherId(String teacherId) {         this.teacherId = teacherId;     }      public String getTeacherName() {         return teacherName;     }      public void setTeacherName(String teacherName) {         this.teacherName = teacherName;     } } 

package com.zzq.spring6.iocxml.dimap;  import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class TestStu {     @Test     public void testStu(){         ApplicationContext context=new                 ClassPathXmlApplicationContext("bean-dimap.xml");         Student student = context.getBean("student", Student.class);         student.run();     } } 
                                                                             10001                                                                                                  10099                                                                                                                       

引入集合类型的bean

1、创建三个对象

2、注入普通类型属性

3、使用util:类型 定义

4、在学生bean引入util:类型定义bean,完成list、map类型属性注入

lesson

package com.zzq.spring6.iocxml.dimap;  public class Lesson {     private String lessonName;      @Override     public String toString() {         return "Lesson{" +                 "lessonName='" + lessonName + '\'' +                 '}';     }      public String getLessonName() {         return lessonName;     }      public void setLessonName(String lessonName) {         this.lessonName = lessonName;     } } 
                                                                                                          10001                                                                          1208                                                                                                                                        

引入p命名空间

                                                                                                                                                 10001                                                                          1208                                                                                                                                        
package com.zzq.spring6.iocxml.dimap;  import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class TestStu {     @Test     public void testStu(){         ApplicationContext context=new                 ClassPathXmlApplicationContext("bean-diref.xml");         Student student = context.getBean("studentp", Student.class);         student.run();     } } 

引入外部属性文件

引入依赖

       mysql     mysql-connector-java     8.0.30         com.alibaba     druid     1.2.15 

创建外部属性文件

jdbc.user=root jdbc.password=root jdbc.url=jdbc:mysql://localhost:3306/spring?serverTimezone=UTC jdbc.driver=com.mysql.cj.jdbc.Driver 

配置bean

                                                       

测试

package com.zzq.spring6.iocxml.jdbc;  import com.alibaba.druid.pool.DruidDataSource; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class TestJdbc {     @Test     public void demo1() {         DruidDataSource dataSource = new DruidDataSource();         dataSource.setUrl("jdbc:mysql://localhost:3306/spring?serverTimezone=UTC");         dataSource.setUsername("root");         dataSource.setPassword("root");         dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");      }     @Test     public void  demo2(){         ApplicationContext context=new                 ClassPathXmlApplicationContext("bean-jdbc.xml");         DruidDataSource dataSource = context.getBean(DruidDataSource.class);         System.out.println(dataSource.getUrl());     } } 

bean的作用域

bean的生命周期

package com.zzq.spring6.iocxml.life;  public class User {     private String name; //无参构造     public User() {         System.out.println("1 bean对象创建,调用无参构造");     } //初始化方法     public void  initMethod(){         System.out.println("4、bean对象初始化,调用指定的初始化方法");     }     //销毁的方法     public void destroyMethod(){         System.out.println("7、bean对象销毁,调用指定的销毁方法");     }     public String getName() {         return name;     }      public void setName(String name) {         System.out.println("2 给bean对象设置属性值");         this.name = name;     } } 
package com.zzq.spring6.iocxml.life;  import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.lang.Nullable;  public class MyBeanPost implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {     System.out.println("3、bean后置处理器,初始化之前执行");     System.out.println(beanName+"::"+bean);         return bean;     } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {     System.out.println("5、bean后置处理器,初始化之后执行");     System.out.println(beanName+"::"+bean);     return bean;     } } 
package com.zzq.spring6.iocxml.life;  import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class TestUser {     public static void main(String[] args) {         ClassPathXmlApplicationContext context=new                 ClassPathXmlApplicationContext("bean-life.xml");         User user = context.getBean("user", User.class);         System.out.println("6  bean对象创建完成,可以使用");         System.out.println(user);         context.close();//销毁对象     } } 
               

FactoryBean

 FactoryBean是Spring提供的一种整合第三方框架的常用机制。和普通的bean不同,配置一个FactoryBean类型的bean,在获取bean的时候得到的并不是class属性中配置的这个类的对象,而是getObject()方法的返回值。通过这种机制,Spring可以帮我们把复杂组件创建的详细过程和繁琐细节都屏蔽起来,只把最简洁的使用界面展示给我们。

将来我们整合Mybatis时,Spring就是通过FactoryBean机制来帮我们创建SqlSessionFactory对象的。

package com.zzq.spring6.iocxml.factorybean;  import org.springframework.beans.factory.FactoryBean;  public class MyFactoryBean implements FactoryBean {     @Override     public User getObject() throws Exception {         return new User();     }      @Override     public Class getObjectType() {         return User.class;     } } 
package com.zzq.spring6.iocxml.factorybean;  import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class TestUser {     public static void main(String[] args) {         ApplicationContext context=new                 ClassPathXmlApplicationContext("bean-factorybean.xml");        User user =(User) context.getBean("user");         System.out.println(user);     } } 
package com.zzq.spring6.iocxml.factorybean;  public class User { } 
   

基于xml自动装配

package com.zzq.spring6.iocxml.auto.controller;  import com.zzq.spring6.iocxml.auto.service.UserService; import com.zzq.spring6.iocxml.auto.service.UserSeviceImpl;  public class UserController {     private UserService userService;      public void setUserService(UserService userService) {         this.userService = userService;     }      public void addUser(){         System.out.println("controller方法执行了");         //调用service的方法         userService.addUserService(); //        UserService userService=new UserSeviceImpl(); //        userService.addUserService();     } } 
package com.zzq.spring6.iocxml.auto.service;  public interface UserService {     public void addUserService(); } 
package com.zzq.spring6.iocxml.auto.service;  import com.zzq.spring6.iocxml.auto.dao.UserDao; import com.zzq.spring6.iocxml.auto.dao.UserDaoImpl;  public class UserSeviceImpl implements UserService {     private  UserDao userDao;      public void setUserDao(UserDao userDao) {         this.userDao = userDao;     }      @Override     public void addUserService() {         System.out.println("userService方法执行了");         userDao.addUserDao(); //        UserDao userDao=new UserDaoImpl(); //        userDao.addUserDao();     } } 
package com.zzq.spring6.iocxml.auto.dao;  public class UserDaoImpl implements UserDao {     @Override     public void addUserDao(){         System.out.println("userDao方法执行了");     } } 
package com.zzq.spring6.iocxml.auto.dao;  import com.zzq.spring6.iocxml.auto.service.UserService;  public interface UserDao { public void addUserDao();  } 
package com.zzq.spring6.iocxml.auto;  import com.zzq.spring6.iocxml.auto.controller.UserController; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class TestUser {     public static void main(String[] args) {         ApplicationContext context=new                 ClassPathXmlApplicationContext("bean-auto.xml");         UserController controller = context.getBean("userController", UserController.class);         controller.addUser();     } } 
                        

自动装配方式:byName
>
> byName:将自动装配的属性的属性名,作为bean的id在IOC容器中匹配相对应的bean进行赋值

基于注解管理Bean

开启组件扫描

   

情况一:最基本的扫描方式**

```xml


```

**情况二:指定要排除的组件**

```xml

   
   
   
       

```

**情况三:仅扫描指定组件**

```xml

   
   
   
   
   
    

```

bean对象的创建

以上四个注解都可实现bean的创建

package com.zzq.bean;  import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service;  @Component(value = "user")//属性可不写,默认为user //@Controller //@Repository //@Service public class User { } 

属性注入

单独使用@Autowired注解,**默认根据类型装配**。【默认是byType】

package com.zzq.autowired.controller;  import com.zzq.autowired.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller;  @Controller public class UserController {     //注入service     //第一种方式属性的注入     @Autowired//根据类型找到对应对象,完成注入     private UserService userService;      public  void add(){         System.out.println("controller...");         userService.add();     } } 
package com.zzq.autowired.service;  import com.zzq.autowired.dao.UserDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;  @Service public class UserServiceImpl implements UserService{     //注入dao      //第一种方式属性注入 //@Autowired //    private UserDao userDao;      //第二种方式set方法注入 //    @Autowired //    private UserDao userDao; // //    public void setUserDao(UserDao userDao) { //        this.userDao = userDao; //    }      //第三种方式:构造方法中注入   private UserDao userDao; @Autowired     public UserServiceImpl(UserDao userDao) {         this.userDao = userDao;     }      @Override     public void add() {         System.out.println("service...");         userDao.add();     } } 
package com.zzq.autowired.controller;  import com.zzq.autowired.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller;  @Controller public class UserController {     //注入service     //第一种方式属性的注入 //    @Autowired//根据类型找到对应对象,完成注入 //    private UserService userService;      //第二种方式set方法注入 //    private UserService userService; //@Autowired //    public void setUserService(UserService userService) { //        this.userService = userService; //    }     //第三种方式 构造方法的注入 //    private UserService userService; //@Autowired //    public UserController(UserService userService) { //        this.userService = userService; //    }      //第四种方式     private UserService userService;      public UserController( @Autowired UserService userService) {         this.userService = userService;     }      public  void add(){         System.out.println("controller...");         userService.add();     } } 

@Autowired注解可以出现在:属性上、构造方法上、构造方法的参数上、setter方法上。
- 当带参数的构造方法只有一个,@Autowired注解可以省略。()
- @Autowired注解默认根据类型注入。如果要根据名称注入的话,需要配合@Qualifier注解一起使用。

@Resource注入

@Resource注解也可以完成属性注入。那它和@Autowired注解有什么区别?

- @Resource注解是JDK扩展包中的,也就是说属于JDK的一部分。所以该注解是标准注解,更加具有通用性。(JSR-250标准中制定的注解类型。JSR是Java规范提案。)
- @Autowired注解是Spring框架自己的。
- **@Resource注解默认根据名称装配byName,未指定name时,使用属性名作为name。通过name找不到的话会自动启动通过类型byType装配。**
- **@Autowired注解默认根据类型装配byType,如果想根据名称装配,需要配合@Qualifier注解一起用。**
- @Resource注解用在属性上、setter方法上。
- @Autowired注解用在属性上、setter方法上、构造方法上、构造方法参数上。

@Resource注解属于JDK扩展包,所以不在JDK当中,需要额外引入以下依赖:【**如果是JDK8的话不需要额外引入依赖。高于JDK11或低于JDK8需要引入以下依赖。**】

     jakarta.annotation     jakarta.annotation-api     2.1.1 

package com.zzq.resource.controller;  import com.zzq.resource.service.UserService; import jakarta.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller;  @Controller("myUserController") public class UserController {     //根据名称进行注入 //@Resource(name = "myUserService") //private UserService userService;     //根据类型进行注入     @Resource     private UserService userService;      public  void add(){         System.out.println("controller...");        userService.add();     } } 

Spring全注解开发

package com.zzq.config;  import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;  @Configuration//配置类 @ComponentScan("com.zzq")//开启组件扫描 public class SpringConfig { } 
package com.zzq.resource;  import com.zzq.config.SpringConfig; import com.zzq.resource.controller.UserController; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class TestUserControllerAnno {     public static void main(String[] args) {         //加载配置类        ApplicationContext context=                new AnnotationConfigApplicationContext(SpringConfig.class);         UserController controller = context.getBean(UserController.class);         controller.add();     }  }

java反射机制

package com.zzq;  import org.junit.jupiter.api.Test;  import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;  public class TestCar {     //1、获取clas对象多种方式      @Test     public void test01() throws Exception { //1、类名.class         Class clazz1 = Car.class;         //2、对象.getclass()         Class clazz2 = new Car().getClass();         //3、Class.forname("全路径")         Class clazz3 = Class.forName("com.zzq.Car"); //实例化         Car car = (Car) clazz3.getDeclaredConstructor().newInstance();         System.out.println(car);     }      //2、通过反射获取构造方法     @Test     public void test02() throws Exception {         Class clazz = Car.class;         //获取所有构造         Constructor[] constructors = clazz.getConstructors();         for (Constructor c : constructors) {             System.out.println("方法个数" + c.getName() + "参数个数" + c.getParameterCount());          }         //指定有参数构造创建对象         //1、构造public //    Constructor c1=clazz.getConstructor(String.class,int.class, String.class); //    Car car1 = (Car)c1.newInstance("本部", 10, "黄色"); //    System.out.println(car1);         //2、构造private         Constructor c2 = clazz.getDeclaredConstructor(String.class, int.class, String.class);         c2.setAccessible(true);         Car car2 = (Car) c2.newInstance("部", 11, "黄色");         System.out.println(car2);     }      //3、获取属性     @Test     public void test03() throws Exception {         Class clazz = Car.class;         //实例化         Car car = (Car) clazz.getDeclaredConstructor().newInstance();         //获取所有的public属性         //    Field[]fields=clazz.getFields();         //获取所有属性(包含私有属性)         Field[] fields = clazz.getDeclaredFields();         for (Field field : fields) {             if (field.getName().equals("name")) {                 field.setAccessible(true);                 field.set(car, "奥迪");             }             System.out.println(field.getName());             System.out.println(car);         }          }     //4、获取方法     @Test     public void test04() throws Exception { Car car=new Car("宝马",19,"黑色"); Class clazz=car.getClass(); //public方法         Method[]methods=clazz.getMethods();         for (Method m1:methods              ) {           //  System.out.println(m1.getName());             //执行方法toString             if (m1.getName().equals("toString")){                 String invoke=(String) m1.invoke(car);               //  System.out.println("toString执行了:"+invoke);         }             //private方法             Method[] methodsAll = clazz.getDeclaredMethods();             for (Method m:methodsAll){                 if (m.getName().equals("run")){                     m.setAccessible(true);                     m.invoke(car);                 }               }         }      }     } 

实现Spring的IoC

ApplicationContext.java

package com.zzq.Bean;  import com.zzq.anno.Bean;  public interface ApplicationContext {      Object getBean(Class clazz); } 

AnnotationApplicationContext.java

package com.zzq.Bean;  import com.zzq.anno.Bean; import com.zzq.anno.Di;  import java.io.File; import java.lang.reflect.Field; import java.net.URL; import java.net.URLDecoder; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Set;  public class AnnotationApplicationContext implements ApplicationContext {     //创建map集合,放bean对象     private   Map beanFactory = new HashMap<>();       private static String rootPath;      //返回对象     @Override     public Object getBean(Class clazz) {         return beanFactory.get(clazz);     }      //设置包扫描规则     //当前包及其子包,拿个类有@Bean注解,把这个类通过反射实例化      public AnnotationApplicationContext(String basePackage) {    // public static void pathdemo1(String basePackage) {         //把.替换成\         try {             String packagePath = basePackage.replaceAll("\\.", "\\\\");             //获取包绝对路径             Enumeration urls = Thread.currentThread().getContextClassLoader().getResources(packagePath);             while (urls.hasMoreElements()) {                 URL url = urls.nextElement();                 String filePath = URLDecoder.decode(url.getFile(), "utf-8");                 //获取包前面路径得到部分,字符串截取                   rootPath = filePath.substring(0, filePath.length() - packagePath.length());                 //包扫描                   loadBean(new File(filePath));             }         } catch (Exception e) {             throw new RuntimeException(e);         }         //属性得到注入          loadDi();     }       //    //包扫描的过程,实例化    private  void loadBean(File file) throws Exception {        //1、判断当前是否文件夹        if (file.isDirectory()) {            //2、获取文件夹里面所有内容            File[] childrenFiles = file.listFiles();            //3、判断文件夹里面为空,直接返回            if (childrenFiles == null || childrenFiles.length == 0) {                return;            }            //4、如果文件夹里面不为空,遍历文件夹所有内容            for (File child : childrenFiles) {                //4.1遍历得到某个File对象,继续判断,如果还是文件,                if (child.isDirectory()) {                    //递归                    loadBean(child);                } else {                    //4.2遍历得到File对象不是文件夹,是文件                    //4.3得到包路径+类名称部分-字符串截取                    String pathWithClass = child.getAbsolutePath().substring(rootPath.length() - 1);                    //4.4判断当前文件类型是否.class                    if (pathWithClass.contains(".class")) {                        //4.5如果是.class类型,把路径\替换. 把class去掉                        String allName = pathWithClass.replaceAll("\\\\", ".")                                .replace(".class", "");                        //4.6判断类上面是否有注解@Bean,如果有实例化过程                        //4.6.1获取类发class                        Class clazz = Class.forName(allName);                        //4.6.2判断不是接口                        if (!clazz.isInterface()) {                            //4.6.3判断类上面是否有注解@Bean                            Bean annotation = clazz.getAnnotation(Bean.class);                            if ((annotation != null)) {                                //4.6.4实例化                                Object instance = clazz.getConstructor().newInstance();                                //4.7把对象实例化之后,放到map集合beanFactory                                //4.7.1判断当前类如果有接口,让接口class作为map的key                                if (clazz.getInterfaces().length > 0) {                                    beanFactory.put(clazz.getInterfaces()[0], instance);                                } else {                                    beanFactory.put(clazz, instance);                                }                            }                        }                    }                }            }         }     } //属性注入     private void loadDi()  {         //实例化对象在beanFactory的map集合里面         //1、遍历beanFactory的map集合         Set>entries=beanFactory.entrySet();         for (Map.Entryentry:entries) { //2、获取map集合每个对象(value),每个对象属性获取到             Object obj=entry.getValue();             //获取对象Class                 Class clazz=obj.getClass();         //获取每个对象的属性             Field[] declaredFields = clazz.getDeclaredFields();             //遍历得到每个对象属性数组,得到每个属性             for (Field field:declaredFields) {                 //4、判断属性上面是否有@Di注解                 Di annotation = field.getAnnotation(Di.class);                 if (annotation != null) {                     //如果私有属性,设置可以设置值                     field.setAccessible(true);                     //5、如果有@Di注解,把对象进行设置(注入)                     try {                         field.set(obj, beanFactory.get(field.getType()));                     }catch (IllegalAccessException e){                         throw new RuntimeException(e);                     }                 }             }         }     }  } 
package com.zzq.anno;  import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;  @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Bean { } 
package com.zzq.anno;  import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;  @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface Di { } 
package com.zzq;  import com.zzq.Bean.AnnotationApplicationContext; import com.zzq.Bean.ApplicationContext; import com.zzq.service.UserService;  public class TestUser {     public static void main(String[] args)  {       ApplicationContext context=               new AnnotationApplicationContext("com.zzq");         UserService userService  = (UserService)context.getBean(UserService.class);         System.out.println(userService);         userService.add();     } } 

相关内容

热门资讯

第七实锤!微扑克外挂辅助软件,... 自定义新版微扑克系统规律,只需要输入自己想要的开挂功能,一键便可以生成出微扑克专用辅助器,不管你是想...
十分钟掌握!中至赣牌圈有挂的!... 自定义新版中至赣牌圈有挂的系统规律,只需要输入自己想要的开挂功能,一键便可以生成出中至赣牌圈有挂的专...
9刹那秒懂!(直隶麻将)外挂透... 9刹那秒懂!(直隶麻将)外挂透视辅助器软件!(透视)详细教程(2024已更新)(哔哩哔哩);德扑锦标...
第二了解!微扑克模拟器外挂透明... 自定义新版微扑克模拟器系统规律,只需要输入自己想要的开挂功能,一键便可以生成出微扑克模拟器专用辅助器...
6分钟体悟!克拉天天踢辅助器可... 6分钟体悟!克拉天天踢辅助器可靠的!(透视)外挂透视辅助器软件(2022已更新)-哔哩哔哩;1、点击...
四刹那秒懂!(万里长城)外挂辅... 自定义新版万里长城系统规律,只需要输入自己想要的开挂功能,一键便可以生成出万里长城专用辅助器,不管你...
9刹那秒懂!(问鼎娱乐)外挂透... 9刹那秒懂!(问鼎娱乐)外挂透明挂辅助器神器!(透视)详细教程(2021已更新)(哔哩哔哩);一、问...
十分钟秒懂!悠闲麻将川南有挂的... 自定义新版悠闲麻将川南有挂的系统规律,只需要输入自己想要的开挂功能,一键便可以生成出悠闲麻将川南有挂...
四瞬间秒懂!(WPK)外挂辅助... 四瞬间秒懂!(WPK)外挂辅助开挂!(透视)详细教程(2021已更新)(哔哩哔哩)是一款可以让一直输...
第二个了解!wEPoke外挂辅... 第二个了解!wEPoke外挂辅助插件,微扑克有辅助挂(有挂解密)-哔哩哔哩;一、微扑克是的,亲,有的...