一个简单的Spring-Bean-自动装配(@Autowired)例子

创建maven空白项目

  1. 这是一个很简单的例子,但是需要一些知识储备,希望对你有用,这只是我的个人笔记,个人的见解。。。

代码架构

在这里插入图片描述

pom.xml文件

  1. pom.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.lihegame.spring</groupId>
	    <artifactId>Spring</artifactId>
	    <version>1.0-SNAPSHOT</version>
	
	    <properties>
	        <!-- Generic properties -->
	        <java.version>1.8</java.version>
	        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	
	        <!-- Spring -->
	        <spring.version>4.2.3.RELEASE</spring.version>
	    </properties>
	
	    <dependencies>
	        <dependency>
	            <groupId>org.springframework</groupId>
	            <artifactId>spring-context</artifactId>
	            <version>${spring.version}</version>
	        </dependency>
	        <dependency>
	            <groupId>log4j</groupId>
	            <artifactId>log4j</artifactId>
	            <version>1.2.17</version>
	        </dependency>
	        <dependency>
	            <groupId>junit</groupId>
	            <artifactId>junit</artifactId>
	            <version>4.12</version>
	            <scope>test</scope>
	        </dependency>
	    </dependencies>
	</project>

log4j.properties文件

  1. log4j.properties
	log4j.rootLogger=DEBUG,Console,File
	
	log4j.appender.Console=org.apache.log4j.ConsoleAppender
	log4j.appender.Console.Target=System.out
	log4j.appender.Console.layout=org.apache.log4j.PatternLayout
	log4j.appender.Console.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH\:mm\:ss,SSS}][%c{1}] - %m%n
	
	log4j.appender.File=org.apache.log4j.RollingFileAppender 
	log4j.appender.File.File=spring.log
	log4j.appender.File.MaxFileSize=10MB
	log4j.appender.File.Threshold=ALL
	log4j.appender.File.layout=org.apache.log4j.PatternLayout
	log4j.appender.File.layout.ConversionPattern=[%d{yyyy-MM-dd HH\:mm\:ss,SSS}][%c]%m%n

如何使用spring的注入bean,使用getBean,使用@Autowired

spring-beans配置文件

  1. userContext.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 http://www.springframework.org/schema/context/spring-context.xsd">
	
	    <!--  配置自动装配  -->
	    <bean id="userCache" class="com.lihegame.spring.user.cache.impl.UserCacheImpl" init-method="init"/>
	
	    <!-- 扫描当前包下的所有带有Cmds注解的类   -->
	    <context:component-scan base-package="com.lihegame.spring.*.cmds">
	        <context:include-filter type="annotation" expression="com.lihegame.spring.anno.Cmds"/>
	    </context:component-scan>
	
	</beans>

编写代码分模块

anno 注解
  1. 这个注解的作用就是为了,区分出哪一个类带有这个注解,如果有这个注解,将其列为需要getBean的对象,然后spring就认识他,把他作为一个对象注入,程序员需要使用这个类,直接可以getBean,这样就可以减去自己new对象的操作,慢慢会知道这样做的好处
  2. Cmds.java
	@Target({ElementType.TYPE, ElementType.METHOD})
	@Retention(RetentionPolicy.RUNTIME)
	public @interface Cmds {
	}
user模块
1、cache
bean
  1. 这是一个存储用户信息的类
  2. User.java
	public class User {
	    private String userName;
	    private String password;
	
	    public String getUserName() {
	        return userName;
	    }
	
	    public void setUserName(String userName) {
	        this.userName = userName;
	    }
	
	    public String getPassword() {
	        return password;
	    }
	
	    public void setPassword(String password) {
	        this.password = password;
	    }
	
	    public User() {
	    }
	
	    public User(String userName, String password) {
	        this.userName = userName;
	        this.password = password;
	    }
	
	    @Override
	    public String toString() {
	        return "User{" +
	                "userName='" + userName + '\'' +
	                ", password='" + password + '\'' +
	                '}';
	    }
	}
2、impl
  1. 这是一个接口实现类,提供用户信息的存储处理,发现有一个init方法,这是一个初始化方法,在上面userContext.xml文件进行了配置,可以在spring扫描到该文件的时候,执行这个ini方法,优点就是想要做些初始化操作,可以放到这个方法里面
  2. UserCacheImpl.java
	public class UserCacheImpl implements UserCache {
	    private final static Map<String, User> userMap = new HashMap<String, User>();
	
	    public User getUser(String userName) {
	        return userMap.get(userName);
	    }
	
	    public boolean saveUser(User user) {
	        userMap.put(user.getUserName(), user);
	        return true;
	    }
	
	    public boolean updateUser(User user) {
	        userMap.put(user.getUserName(), user);
	        return true;
	    }
	
	    public boolean deleteUser(String userName) {
	        userMap.remove(userName);
	        return true;
	    }
	
	    public void init(){
	        System.out.println("初始化!");
	    }
	}
3、接口
  1. 这是一个提供用户信息增删改查方法的接口
  2. UserCache.java
	public interface UserCache {
	    /**
	     * 根据用户名找到用户
	     * @param userName 用户名
	     * @return 用户
	     */
	    User getUser(String userName);
	
	    /**
	     * 根据新用户信息新增新用户
	     * @param user 新用户
	     * @return 是否保存
	     */
	    boolean saveUser(User user);
	
	    /**
	     * 根据新用户信息更新旧用户信息
	     * @param user 新用户信息
	     * @return 是否更新
	     */
	    boolean updateUser(User user);
	
	    /**
	     * 根据用户名删除用户
	     * @param userName  用户名
	     * @return 是否删除
	     */
	    boolean deleteUser(String userName);
	}
cmds
  1. 这是一个逻辑处理层,处理请求命令,通过访问存储层,实现该功能,使用spring注解@Autowired
  2. 注意类的上面有个注解@Cmds,这是用来给spring识别的,只需要扫描有这个注解的类,在配置文件有写到
  3. 想要这个@Autowired成功装配,需要进行上面配置文件的填写,这个月spring就自动帮忙处理好,程序员只需考虑使用,不需要考虑如何创建
	@Cmds
	public class UserCmds {
	    @Autowired
	    private UserCache userCache;
	
	    public User getUser(String userName) {
	        return userCache.getUser(userName);
	    }
	
	    public boolean saveUser(User user) {
	        User u = getUser(user.getUserName());
	        if (u != null) {
	            return false;
	        } else {
	            return userCache.saveUser(user);
	        }
	    }
	
	    public boolean updateUser(User user) {
	        User u = getUser(user.getUserName());
	        if (u == null) {
	            return false;
	        } else {
	            return userCache.updateUser(user);
	        }
	    }
	
	    public boolean deleteUser(String userName) {
	        User u = getUser(userName);
	        if (u == null) {
	            return false;
	        } else {
	            return userCache.deleteUser(userName);
	        }
	    }
	}
扫描beans的spring
  1. 比较重要的一定,配置文件写好,代码写好,需要有一个类去启功spring去读取配置文件,而且可以开放一个对象给其他类使用,其他类也可以使用spring读取的bean
	public class SpringBean {
	    private final static ApplicationContext applicationContext = new ClassPathXmlApplicationContext("context/userContext.xml");
	
	    public static ApplicationContext getApplicationContext() {
	        return applicationContext;
	    }
	}
测试类
  1. 这是一个测试类,所以就直接写代码读取配置文件了
  2. 因为配置文件userContext.xml,已经配置了基本信息,当使用spring读取配置文件,得到getBean获取所有带有注解@Cmds的类,然后bean,接口指向接口实现类,实现@Autowired功能
	public class MainTest {
	
	    public static void main(String[] args) {
	        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("context/userContext.xml");
	        UserCmds userCmds = applicationContext.getBean(UserCmds.class);
	        User user;
	        // 查询-null
	        user = userCmds.getUser("mo");
	        System.out.println(user);
	        // 保存
	        userCmds.saveUser(new User("mo", "123"));
	        // 查询-user
	        user = userCmds.getUser("mo");
	        System.out.println(user);
	        // 更新
	        userCmds.updateUser(new User("mo","111"));
	        // 查询-user
	        user = userCmds.getUser("mo");
	        System.out.println(user);
	        // 删除
	        userCmds.deleteUser("mo");
	        // 查询-null
	        user = userCmds.getUser("mo");
	        System.out.println(user);
	    }
	}
测试结果
  1. 可以认真看看日志记录,spring扫描、创建、初始化。。。他找到需要注入的bean
	[DEBUG][2020-09-25 16:18:08,447][DefaultListableBeanFactory] - Creating shared instance of singleton bean 'userCache'
	[DEBUG][2020-09-25 16:18:08,447][DefaultListableBeanFactory] - Creating instance of bean 'userCache'
	[DEBUG][2020-09-25 16:18:08,456][DefaultListableBeanFactory] - Eagerly caching bean 'userCache' to allow for resolving potential circular references
	[DEBUG][2020-09-25 16:18:08,478][DefaultListableBeanFactory] - Invoking init method  'init' on bean with name 'userCache'
	初始化!
	[DEBUG][2020-09-25 16:18:08,478][DefaultListableBeanFactory] - Finished creating instance of bean 'userCache'
	[DEBUG][2020-09-25 16:18:08,479][DefaultListableBeanFactory] - Creating shared instance of singleton bean 'userCmds'
	[DEBUG][2020-09-25 16:18:08,479][DefaultListableBeanFactory] - Creating instance of bean 'userCmds'
	[DEBUG][2020-09-25 16:18:08,488][InjectionMetadata] - Registered injected element on class [com.lihegame.spring.user.cmds.UserCmds]: AutowiredFieldElement for private com.lihegame.spring.user.cache.UserCache com.lihegame.spring.user.cmds.UserCmds.userCache
	[DEBUG][2020-09-25 16:18:08,489][DefaultListableBeanFactory] - Eagerly caching bean 'userCmds' to allow for resolving potential circular references
	[DEBUG][2020-09-25 16:18:08,490][InjectionMetadata] - Processing injected element of bean 'userCmds': AutowiredFieldElement for private com.lihegame.spring.user.cache.UserCache com.lihegame.spring.user.cmds.UserCmds.userCache
	[DEBUG][2020-09-25 16:18:08,495][DefaultListableBeanFactory] - Returning cached instance of singleton bean 'userCache'
	[DEBUG][2020-09-25 16:18:08,496][AutowiredAnnotationBeanPostProcessor] - Autowiring by type from bean name 'userCmds' to bean named 'userCache'
	[DEBUG][2020-09-25 16:18:08,594][DefaultListableBeanFactory] - Returning cached instance of singleton bean 'userCmds'
	null
	User{userName='mo', password='123'}
	User{userName='mo', password='111'}
	null
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值