Spring系列三:基于注解配置bean 下

news2024/9/27 7:19:48

基于注解配置bean

  • 💗自动装配
    • 🍝`案例1:` @Autowired引出
    • 🍝`案例2:` @Autowired解读
    • 🍚`案例3:` @Resource解读
    • 🍝小结
  • 💗泛型依赖注入
    • 🍝基本说明
    • 🍝应用实例

在这里插入图片描述

💗自动装配

●基本说明
1.基于注解配置bean, 也可实现自动装配. 使用的注解是: @Autowired 或者 @Resource

  • @Autowired的规则说明
    1. 在ioc容器中查找待装配的组件的类型, 如果有唯一的bean则匹配.

    2. 如果装配的类型对应的bean在ioc容器中有多个, 则使用待装配的属性的属性名作为id值再进行查找, 找到就装配, 找不到就抛异常.

  • @Resource的规则说明
    1. @Resource有两个属性是有两个属性是比较重要的, 分别是name和type. Spring将@Resource注解的name属性解析为bean的名字, 将type属性解析为bean的类型.

    2. 如果使用name属性, 则使用byName的自动注入策略; 而使用type属性时, 则使用byType自动注入策略.

    3. 如果@Resource 没有指定 name 和 type, 则优先使用byName注入策略 (即使用待装配的属性的属性名作为id值进行查找), 如果匹配不上, 再使用byType策略(即查找待装配的组件的类型). 如果都不成功, 就会报错.

  1. 不管是@Autowired 还是 @Resource 都保证属性名是规范写法就可以 注入.

🍝案例1: @Autowired引出

@Service
public class UserService {
    public void hi() {
        System.out.println("UserService hi()...");
    }
}
@Controller
public class UserAction {
    
    private UserService userService;
    
    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        userService.hi();
    }
}
<?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 http://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.zzw.spring.component"/>
</beans>
public class SpringBeanTest {
    @Test
    public void setPropertyByAutowired() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans06.xml");
        UserAction userAction = ioc.getBean("userAction", UserAction.class);
        System.out.println("userAction=" + userAction);//这里会输出
        userAction.sayOK();//这里会报空指针异常
    }
}

加入@Autowired, 就不会报错了.

@Controller
public class UserAction {
    @Autowired
    private UserService userService;
    
    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        userService.hi();
    }
}

小知识点: OOP中我们是通过这种方式注入对象的, 注意比对.

public class UserAction {

    private UserService userService = new UserService();
    
    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        userService.hi();
    }
}

🍝案例2: @Autowired解读

下面的代码中, UserAction中的userService200 和 SpringBeanTest中的userService是同一个对象. 因为ioc容器中只有一个UserService类型的对象, 此时按照类型来匹配.

@Service
public class UserService {
    public void hi() {
        System.out.println("UserService hi()...");
    }
}
@Controller
public class UserAction {
    //原先的xml配置, 我们会配置ref. 但是注解配置的情况下, 我们会用@Autowired
    //说明
    //1.在ioc容器中查找待装配的组件的类型, 如果有唯一的bean匹配(按照类型), 则使用该bean匹配
    //2.如果待装配的类型对应的bean在ioc容器中有多个, 则使用待装配的属性的属性名作为id值再进行查找
    //  找到就装配, 找不到就抛异常
    @Autowired
    private UserService userService200;

    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        System.out.println("UserAction 装配的 userService属性=" + userService200);
        userService200.hi();
    }
}
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
       
	<!--通过注解获取的对象id是类名首字母小写-->
    <context:component-scan base-package="com.zzw.spring.component"/>
</beans>
public class SpringBeanTest {
    @Test
    public void setPropertyByAutowired() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans06.xml");
                
        UserService userService = ioc.getBean("userService", UserService.class);
        System.out.println("ioc容器中的userService=" + userService);

        UserService userService200 = ioc.getBean("userService200", UserService.class);
        System.out.println("ioc容器中的userService200=" + userService200);

        UserAction userAction = ioc.getBean("userAction", UserAction.class);
        userAction.sayOK();
    }
}

如果在beans06.xml中加入了同一类型(UserService)的对象, 如下. 那么UserAction中的userService200 和 SpringBeanTest中的userService将不再是同一个对象. 因为ioc容器中UserService类型的对象有多个, 此时将按照待匹配属性的属性名作为id值来匹配, 匹配到的是id为userService200的对象.

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

    <!--通过注解获取的对象id是类名首字母小写-->
    <context:component-scan base-package="com.zzw.spring.component"/><!--id=userService-->

    <!--配置两个UserService对象-->
    <bean class="com.zzw.spring.component.UserService" id="userService200"/>
    <bean class="com.zzw.spring.component.UserService" id="userService300"/>
</beans>

如果UserAction改为如下情况, 那么将会报错. 因为此时是按照待匹配属性的属性名作为id值来匹配的, 但beans06.xml中并没有id=userService400的bean对象, 所以报错.

@Controller
public class UserAction {
    //原先的xml配置, 我们会配置ref. 但是注解配置的情况下, 我们会用@Autowired
    //说明
    //1.在ioc容器中查找待装配的组件的类型, 如果有唯一的bean匹配(按照类型), 则使用该bean匹配
    //2.如果待装配的类型对应的bean在ioc容器中有多个, 则使用待装配的属性的属性名作为id值再进行查找
    //  找到就装配, 找不到就抛异常
    @Autowired
    private UserService userService400;

    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        System.out.println("UserAction 装配的 userService属性=" + userService400);
        userService400.hi();
    }
}

指定id进行组装. 可以使用@Autowired和@Qualifier(value=“userService200”). 这时, 是装配的 id=userService200, 两个注解要配合使用, 类似于@Resource(name="userService200").
此时, UserAction中的userService 和 SpringBeanTest中的userService200是同一个对象.

@Controller
public class UserAction {
    //指定id进行组装. 可以使用@Autowired和@Qualifier(value="userService200"). 
    //这时, 是装配的 id=userService200, 类似于@Resource(name="userService200").
    //前提是需要两个注解都写上. 
    @Autowired
    @Qualifier(value = "userService200")
    private UserService userService;

    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        System.out.println("UserAction 装配的 userService属性=" + userService);
        userService.hi();
    }
}
public class SpringBeanTest {
    @Test
    public void setPropertyByAutowired() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans06.xml");
                
        UserService userService = ioc.getBean("userService", UserService.class);
        System.out.println("ioc容器中的userService=" + userService);

        UserService userService200 = ioc.getBean("userService200", UserService.class);
        System.out.println("ioc容器中的userService200=" + userService200);

        UserAction userAction = ioc.getBean("userAction", UserAction.class);
        userAction.sayOK();
    }
}

🍚案例3: @Resource解读

@Resource源码解读: 通过解析注解来支撑, 底层是注解来支撑的.
String name() default "";
Class<?> type() default java.lang.Object.class;

@Resource(name = "userService") 代表把beans06.xml对应的容器里的id=userService的对象注入到属性上去, 所以UserAction中的userService400 和 SpringBeanTest中的userService是同一个对象

@Controller
public class UserAction {

    //1.@Resource 有两个属性是比较重要的, 分别是name和type, Spring将@Resource注解的name属性解析为bean的名字,
    //  将type属性解析为bean的类型. 所以如果使用name属性, 则使用byName的自动注入策略, 而使用type属性时则使用
    //  byType自动注入策略
    //  比如 @Resource(name="userService") 表示装配id=userService的对象
    //  比如 @Resource(type="UserService.class") 表示按照UserService.class类型进行装配. 这时要求容器中,只能有一个这样类型的对象
    //2.如果@Resource 没有指定 name 和 type, 则先使用byName注入策略 (即使用待装配的属性的属性名作为id值进行查找),
    //  如果匹配不上, 再使用byType策略. 如果都不成功, 就会报错.
    @Resource(name = "userService")
    private UserService userService400;

    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        System.out.println("UserAction 装配的 userService属性=" + userService400);
        userService400.hi();
    }
}
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--通过注解获取的对象id是类名首字母小写, 这里是userService-->
    <context:component-scan base-package="com.zzw.spring.component"/><!--id=userService-->

    <!--配置两个UserService对象-->
    <bean class="com.zzw.spring.component.UserService" id="userService200"/>
    <bean class="com.zzw.spring.component.UserService" id="userService300"/>
</beans>
public class SpringBeanTest {

    @Test
    public void setPropertyByAutowired() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans06.xml");
                
        UserService userService = ioc.getBean("userService", UserService.class);
        System.out.println("ioc容器中的userService=" + userService);

        UserAction userAction = ioc.getBean("userAction", UserAction.class);
        userAction.sayOK();
    }
}

如果将代码改为@Resource(name = "userService200") 代表把beans06.xml对应的容器里的id=userService200的对象注入到属性上去, 那么UserAction中的userService400 和 SpringBeanTest中的userService200将是同一个对象,

@Controller
public class UserAction {

    //1.@Resource 有两个属性是比较重要的, 分别是name和type, Spring将@Resource注解的name属性解析为bean的名字,
    //  将type属性解析为bean的类型. 所以如果使用name属性, 则使用byName的自动注入策略, 而使用type属性时则使用
    //  byType自动注入策略
    //  比如 @Resource(name="userService") 表示装配id=userService的对象
    @Resource(name = "userService200")
    private UserService userService400;

    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        System.out.println("UserAction 装配的 userService属性=" + userService400);
        userService400.hi();
    }
}
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--通过注解获取的对象id是类名首字母小写, 这里是userService-->
    <context:component-scan base-package="com.zzw.spring.component"/><!--id=userService-->

    <!--配置两个UserService对象-->
    <bean class="com.zzw.spring.component.UserService" id="userService200"/>
    <bean class="com.zzw.spring.component.UserService" id="userService300"/>
</beans>
public class SpringBeanTest {

    @Test
    public void setPropertyByAutowired() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans06.xml");
                
        UserService userService = ioc.getBean("userService", UserService.class);
        System.out.println("ioc容器中的userService=" + userService);

        UserService userService200 = ioc.getBean("userService200", UserService.class);
        System.out.println("ioc容器中的userService200=" + userService200);

        UserAction userAction = ioc.getBean("userAction", UserAction.class);
        userAction.sayOK();
    }
}

如果将代码改为@Resource(name = "userService600") 会直接报错. 因为beans06.xml对应的容器中没有id为userService600的对象, 所以报错.

@Controller
public class UserAction {

    //1.@Resource 有两个属性是比较重要的, 分别是name和type, Spring将@Resource注解的name属性解析为bean的名字,
    //  将type属性解析为bean的类型. 所以如果使用name属性, 则使用byName的自动注入策略, 而使用type属性时则使用
    //  byType自动注入策略
    //  比如 @Resource(name="userService") 表示装配id=userService的对象
    @Resource(name = "userService600")
    private UserService userService400;

    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        System.out.println("UserAction 装配的 userService属性=" + userService400);
        userService400.hi();
    }
}
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--通过注解获取的对象id是类名首字母小写, 这里是userService-->
    <context:component-scan base-package="com.zzw.spring.component"/><!--id=userService-->

    <!--配置两个UserService对象-->
    <bean class="com.zzw.spring.component.UserService" id="userService200"/>
    <bean class="com.zzw.spring.component.UserService" id="userService300"/>
</beans>

如果按照类型来装配, @Resource(type = UserService.class), 那么必须保证容器中该类型的对象只有一个.
像下面的情况就会报错.

public class UserAction {

    @Resource(type = UserService.class)
    private UserService userService400;

    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        System.out.println("UserAction 装配的 userService属性=" + userService400);
        userService400.hi();
    }
}
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--通过注解获取的对象id是类名首字母小写-->
    <context:component-scan base-package="com.zzw.spring.component"/><!--id=userService-->

    <!--配置两个UserService对象-->
    <bean class="com.zzw.spring.component.UserService" id="userService200"/>
    <bean class="com.zzw.spring.component.UserService" id="userService300"/>
</beans>

如果@Resource 没有指定 name 和 type, 则先使用byName注入策略 (即使用待装配的属性的属性名作为id值进行查找),如果匹配不上, 再使用byType策略. 如果都不成功, 就会报错. 像下面的代码就会报错.

public class UserAction {

    //2.如果@Resource 没有指定 name 和 type, 则先使用byName注入策略 (即使用待装配的属性的属性名作为id值进行查找),
    //  如果匹配不上, 再使用byType策略. 如果都不成功, 就会报错.
    @Resource
    private UserService userService400;

    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        System.out.println("UserAction 装配的 userService属性=" + userService400);
        userService400.hi();
    }
}
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--通过注解获取的对象id是类名首字母小写-->
    <context:component-scan base-package="com.zzw.spring.component"/><!--id=userService-->

    <!--配置两个UserService对象-->
    <bean class="com.zzw.spring.component.UserService" id="userService200"/>
    <bean class="com.zzw.spring.component.UserService" id="userService300"/>
</beans>

下面代码会成功

public class UserAction {

    //2.如果@Resource 没有指定 name 和 type, 则先使用byName注入策略 (即使用待装配的属性的属性名作为id值进行查找),
    //  如果匹配不上, 再使用byType策略. 如果都不成功, 就会报错.
    @Resource
    private UserService userService;

    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        System.out.println("UserAction 装配的 userService属性=" + userService);
        userService.hi();
    }
}

下面代码依然会成功

public class UserAction {

    //2.如果@Resource 没有指定 name 和 type, 则先使用byName注入策略 (即使用待装配的属性的属性名作为id值进行查找),
    //  如果匹配不上, 再使用byType策略. 如果都不成功, 就会报错.
    @Resource
    private UserService userService200;

    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        System.out.println("UserAction 装配的 userService属性=" + userService200);
        userService200.hi();
    }
}

下面代码会失败. 因为beans.xml中没有id=userServise600的bean对象, byName注入策略不成功, 并且byType注入策略也不成功, 所以会失败.

public class UserAction {

    //2.如果@Resource 没有指定 name 和 type, 则先使用byName注入策略 (即使用待装配的属性的属性名作为id值进行查找),
    //  如果匹配不上, 再使用byType策略. 如果都不成功, 就会报错.
    @Resource
    private UserService userService600;

    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        System.out.println("UserAction 装配的 userService属性=" + userService600);
        userService600.hi();
    }
}

但是下面的代码会成功. 虽然beans.xml中没有id=userServise600的bean对象, 即byName注入策略不成功, 但是由于beans06.xml对应的容器中只有一个UserService类型的对象, 所以byType策略成功, 所以下面代码不会报错.

public class UserAction {

    //2.如果@Resource 没有指定 name 和 type, 则先使用byName注入策略 (即使用待装配的属性的属性名作为id值进行查找),
    //  如果匹配不上, 再使用byType策略. 如果都不成功, 就会报错.
    @Resource
    private UserService userService600;

    public void sayOK() {
        System.out.println("UserAction sayOK()....");
        System.out.println("UserAction 装配的 userService属性=" + userService600);
        userService600.hi();
    }
}
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--通过注解获取的对象id是类名首字母小写-->
    <context:component-scan base-package="com.zzw.spring.component"/><!--id=userService-->

    <!--配置两个UserService对象-->
    <!--<bean class="com.zzw.spring.component.UserService" id="userService200"/>-->
    <!--<bean class="com.zzw.spring.component.UserService" id="userService300"/>-->
</beans>

🍝小结

1.如果装配的类型对应的bean在IOC容器中有多个, 则使用待装配的属性的属性名作为id值再进行查找, 找到就装配, 找不到就抛异常.

💗泛型依赖注入

🍝基本说明

1.为了更好地管理有继承和相互依赖的bean的自动装配, spring还提供基于泛型依赖的注入机制.

2.在继承关系复杂情况下, 泛型依赖注入就会有很大的优越性.

各个类关系图
在这里插入图片描述


传统方法是将 PhoneDao / BookDao 自动装配到 BookService / PhoneService中, 当这种继承关系多时, 就比较麻烦. 可以使用spring提供的泛型依赖注入.

🍝应用实例

public class Book {}
public class Phone {}
//自定义泛型类
public abstract class BaseDao<T> {
    public abstract void save();
}
@Repository
public class BookDao extends BaseDao<Book> {
    @Override
    public void save() {
        System.out.println("BookDao的 save方法....");
    }
}
@Repository
public class PhoneDao extends BaseDao<Phone> {
    @Override
    public void save() {
        System.out.println("PhoneDao的 save方法...");
    }
}
//自定义泛型类
public class BaseService<T> {
    @Autowired
    private BaseDao<T> baseDao;

    public void save() {
        baseDao.save();
    }
}
@Service
public class BookService extends BaseService<Book> {
    //并没有写属性
}
@Service
public class PhoneService extends BaseService<Phone> {
    //没有写属性
}

beans07.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 http://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.zzw.spring.depinjection"/>
</beans>
public class SpringBeanTest {

    @Test
    public void setProByDependencyInjection() {
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans07.xml");

        PhoneService phoneService = ioc.getBean("phoneService", PhoneService.class);
        phoneService.save();//PhoneDao的 save方法...
        System.out.println("OK");
    }
}

在这里插入图片描述
在这里插入图片描述下乘: Spring系列四:AOP切面编程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1920168.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据中心巡检机器人助力,河南某数据中心机房智能化辅助项目交付

随着数据中心规模的不断扩大和业务需求的不断增长&#xff0c;确保其高效、安全、稳定地运行变得愈发重要。传统的人力巡检方式存在效率低、误差高、成本大等问题&#xff0c;难以满足现代数据中心的需求。为解决这些挑战&#xff0c;智能巡检机器人应运而生&#xff0c;成为数…

应用最优化方法及MATLAB实现——第3章代码实现

一、概述 在阅读最优方法及MATLAB实现后&#xff0c;想着将书中提供的代码自己手敲一遍&#xff0c;来提高自己对书中内容理解程度&#xff0c;巩固一下。 这部分内容主要针对第3章的内容&#xff0c;将其所有代码实现均手敲一遍&#xff0c;中间部分代码自己根据其公式有些许的…

Windows系统MySQL的安装,客户端工具Navicat的安装

下载mysql安装包&#xff0c;可以去官网下载&#xff1a;www.mysql.com。点击downloads 什么&#xff1f;后面还有福利&#xff1f; 下载MySQL 下载企业版&#xff1a; 下载Windows版 5点多的版本有点低&#xff0c;下载8.0.38版本的。Window系统。下载下面的企业版。不下载…

网安防御保护-小实验

1、DMZ区内的服务器&#xff0c;办公区仅能在办公时间内(9:00-18:00)可以访问&#xff0c;生产区的设备全天可以访问 2、生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网 3、办公区设备10.0.2.10不允许访问DMZ区的FTP服务器和HTTP服务器&#xff0c;仅能ping通…

Android Settings应用 PreferenceScreen 条目隐藏实现和简单分析

Android Settings应用 PreferenceScreen 条目隐藏实现和简单分析 文章目录 Android Settings应用 PreferenceScreen 条目隐藏实现和简单分析一、前言二、隐藏实现1、xml 文件中隐藏PreferenceScreen 的某个条目2、普通Preference条目的隐藏的Java代码实现3、SwitchPreference条…

bevfomer self-att to transformer to tensorrt

self-attentation https://blog.csdn.net/weixin_42110638/article/details/134016569 query input* Wq key input* Wk value input* Wv output 求和 query . key * value detr multiScaleDeformableAttn Deformable Attention Module&#xff0c;在图像特征上&#…

STM32读取LX-224总线舵机信息

一、舵机指令包格式 帧头&#xff1a; 连续收到两个 0x55 ,表示有数据包到达。ID: 每个舵机都有一个 ID 号。ID 号范围 0&#xff5e;253,转换为十六进制 0x00&#xff5e;0xFD。广播 ID: ID 号 254(0xFE) 为广播 ID,若控制器发出的 ID 号为 254(0xFE)&#xff0c;所有的舵机均…

DockerFile文件解析

DockerFile 要研究自己如何做一个镜像&#xff0c;而且微服务项目打包上云部署&#xff0c;Docker就是最方便的。 微服务打包成镜像&#xff0c;任何装了Docker的地方&#xff0c;都可以下载使用&#xff0c;极其的方便。 流程&#xff1a;开发应用>DockerFile>打包为…

c++ 建造者模式

文章目录 建造者模式为什么使用建造者模式建造者模式实现步骤实现示例建造者模式优缺点 建造者模式 建造者模式&#xff08;Builder Pattern&#xff09;是面向对象设计模式中的一种&#xff0c;主要用于创建复杂对象。这种模式将对象的构建过程与其表示分离&#xff0c;允许用…

Qt+ESP32+SQLite 智能大棚

环境简介 硬件环境 ESP32、光照传感器、温湿度传感器、继电器、蜂鸣器 基本工作流程 上位机先运行&#xff0c;下位机启动后尝试连接上位机连接成功后定时上报传感器数据到上位机&#xff0c;上位机将信息进行处理展示判断下位机传感器数据&#xff0c;如果超过设置的阈值&a…

电商出海第一步,云手机或成重要因素

电商出海第一步并非易事&#xff0c;挑战和机遇并存&#xff0c;出海企业或个人或将借助云手机从而达成商业部署全球化的目的&#xff1b; 下面我们从网络稳定、数据安全、成本、以及多平台适配方面来看&#xff0c;究竟为什么说云手机会成为出海的重要因素&#xff1b; 首先…

图谱动态240709

本期将分享近期全球知识图谱相关 行业动态、会议资讯、论文推荐 —--| 行业动态 |--— 微软开源GraphRAG 7月2日&#xff0c;微软开源了GraphRAG&#xff0c;一种基于图的检索增强生成(RAG) 方法&#xff0c;可以对私有或以前未见过的数据集进行问答&#xff08;开源地址&…

ENSP防火墙

实验拓扑图 需求&#xff1a; ENSP的配置&#xff1a; 防火墙&#xff1a; 交换机&#xff1a; 华为防火墙的配置&#xff1a; 接口配置&#xff1a; 安全区域&#xff1a; 安全策略&#xff1a; 办公区访问DMZ&#xff1a; 生产区访问DMZ&#xff1a; 游客区只能访问门户网…

USB转RS485+RS232+TTL串口电路

USB转RS485RS232TTL电路 USB转RS485RS232TTL电路如下图所示&#xff0c;可实现USB转RS485RS232TTL串口&#xff0c;一个电路模块即可实现电路调试过程中用到常用接口。 电路模块上留有2.54MM单排针接口和接线端子两种接线方式&#xff0c;可接线和跳线。电路模块同时有5V和3.3V…

Vulkan入门系列0- Vulkan与OpenGL的区别

一:概述 Vulkan 是新一代图形和计算API,是由科纳斯组织(Khronos Group)维护的一套跨平台的、开放标准的、现代GPU 的编程接口,它仅仅是规定了一套编程接口,并没有接口的具体实现,实现是由硬件厂商适配实现的,市面上像NVIDIA、AMD和Intel等国际大厂基本提供了完整的…

C++ enum class转常量

当使用 enum class 时&#xff0c;它具有更强的类型安全性和隔离性&#xff0c;因此需要显式转换才能访问其底层整数值。 std::underlying_type_t 是一个类型别名&#xff0c;它返回枚举类型的底层类型。 to_underlying 函数提供了一种方便的方式来执行这种转换&#xff0c;特别…

vb.netcad二开自学笔记8:界面之任务窗格

使用net可以创建一个类似属性面板的自定义的任务窗格&#xff0c;从而实现应用程序更丰富的人机交互。 1、添加一个自定义控件 2、在前面创建的代码框架内增加一个命令函数ShowMyPalette Imports System.Windows.Media.Imaging Imports Autodesk.AutoCAD.ApplicationServices …

python的简单爬取

需要的第三方模块 requests winr打开命令行输入cmd 简单爬取的基本格式&#xff08;爬取百度logo为例&#xff09; import requests url"http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" resprequests.get(url)#回应 #保存到本地 with open(&…

5G中的RedCap

5G中的RedCap&#xff1a;降低能力的重要性和实现方式 随着5G技术的推广和普及&#xff0c;设备和终端的多样化使得网络能力的管理变得更加复杂和关键。RedCap&#xff08;Reduced Capability&#xff09;作为一个重要的概念&#xff0c;旨在解决设备能力差异对网络服务和用户…