Autowired must be defined in Spring bean @Component/@Service
Spring@Autowired注解与省去get和set方法,对注解Autowired放在setter方法上的情况
springboot中@Autowired 注入失效的四种原因及解决方法
Spring@Autowired注解与省去get和set方法,对注解Autowired放在setter方法上的情况
@Autowired详解
要搞明白@Autowired注解就是要了解它是什么?有什么作用?怎么用?为什么?
首先了解一下IOC操作Bean管理,**bean管理是指(1)spring创建对象 (2)spring注入属性。**当我们在将一个类上标注@Service或者@Controller或@Component或@Repository注解之后,spring的组件扫描就会自动发现它,并且会将其初始化为spring应用上下文中的bean。 当需要使用这个bean的时候,例如加上@Autowired注解的时候,这个bean就会被创建。而且初始化是根据无参构造函数。
先看代码来体会一下这个注解的作用,测试代码如下:(@Data注解是由Lombok库提供的,会生成getter、setter以及equals()、hashCode()、toString()等方法)
@Autowired
这个注解就是spring可以自动帮你把bean里面引用的对象的setter/getter方法省略,它会自动帮你set/get。
<bean id="userDao" class="..."/>
<bean id="userService" class="...">
<property name="userDao">
<ref bean="userDao"/>
property>
bean>
这样你在userService里面要做一个userDao的setter/getter方法。
但如果你用了@Autowired的话,你只需要在UserService的实现类中声明即可。
@Autowired
private IUserDao userdao;
在applicatonContext.xml中 把原来 引用的标签也去掉。
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
这样,当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。
按照上面的配置,Spring 将直接采用 Java 反射机制对 Boss 中的 car 和 office 这两个私有成员变量进行自动注入。所以对成员变量使用 @Autowired 后,您大可将它们的 setter 方法(setCar() 和 setOffice())从Boss 中删除。
public class Boss {
@Autowired
private Car car;
@Autowired
private Office office;
}
<bean id="userDao4" class="cn.itcast.spring.UserDaoImpl" />
<bean id ="userService" class="cn.itcast.spring.UserServiceImpl">
<!-- 注入对象 -->
<!-- property 根据类中的setter方法进行属性注入 -->
<!-- name:setter方法的后缀小写,比如setXxx 对应的name为xxx -->
<!-- ref:引用哪一个bean(对象),值为bean的id/name -->
<!--用了Autowired就删掉Property,ref,否则报错-->
<!-- <property name="userDao4" ref="userDao4" />-->
</bean>
App.java
import beans.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
public class App {
public static void main(String[] args) {
// 方法一: 通过 ApplicationContext 来获取 Spring 的上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//根据上下文对象提供的方法获取到 Bean
User user1 = (User) context.getBean("user");
user1.sayHi("Spring1");
// 方法二: 通过 BeanFactory 来获取 Spring 的上下文对象
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
//通过类型获取
User user2 = beanFactory.getBean(User.class);
user2.sayHi("Spring2");
// 方法三: 通过 id+类型 来获取
User user3 = context.getBean("user",User.class);
user3.sayHi("Spring3");
}
}
IUserDao
package cn.itcast.spring;
public interface IUserDao {
public void findByUsernameAndPassword();
}
IUserService
package cn.itcast.spring;
//业务层
public interface IUserService {
//登录
public void login();
}
UserDaoFactory
package cn.itcast.spring;
public class UserDaoFactory {
//提供获取对象的方法
public UserDaoImpl getUserDAO() {
//返回实例对象
return new UserDaoImpl();
}
//利用反射技术生产具体类型的实例对象
public Object getBean() {
Object bean = null;
try {
//传入类字符串,生产对象实例
bean = Class.forName("cn.itcast.spring.UserDaoImpl").newInstance();
} catch (Exception e) {
e.printStackTrace();
}
//返回具体类型的对象类型实例
return bean;
}
}
UserDaoImpl
package cn.itcast.spring;
public class UserDaoImpl implements IUserDao {
public static int count = 1;
public static void countMethod() {
count++;
}
@Override
public void findByUsernameAndPassword() {
System.out.println("UserDaoImpl-dao层被调用" + count + "次了");
countMethod();
}
}
UserServiceImpl
package cn.itcast.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
//业务层实现
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao userDao4;
/* public void setUserDao4(IUserDao userDao4){
this.userDao4 = userDao4;
}*/
@Override
public void login() {
System.out.println("UserServiceImpl-service层被调用了。。。");
//方式1
//实例化dao层
IUserDao userDao = new UserDaoImpl();
userDao.findByUsernameAndPassword();
//创建工厂
UserDaoFactory userDaoFactory = new UserDaoFactory();
//方式2
UserDaoImpl userDao1 = userDaoFactory.getUserDAO();
userDao1.findByUsernameAndPassword();
//方式3
//使用反射方法获取对象
IUserDao userDao2 = (IUserDao) userDaoFactory.getBean();
userDao2.findByUsernameAndPassword();
//方式4
//spring配置方式,创建spring工厂,加载spring配置文件
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//从spring工厂中获取对象,通过bean的id/name
IUserDao userDao3 = (IUserDao) ac.getBean("userDao3");
userDao3.findByUsernameAndPassword();
//方式5
//不创建工厂
userDao4.findByUsernameAndPassword();
}
}
UserServiceImplTest
package cn.itcast.spring;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserServiceImplTest {
@Test
public void login() {
/* UserServiceImpl userService = new UserServiceImpl();
userService.login();*/
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
IUserService userService1 = (IUserService) ac.getBean("userService");
userService1.login();
}
}
log4j.properties
log4j.rootLogger=INFO,A1
log4j.logger.org.apache=INFO
log4j.appender.A1.Target=System.err
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n
spring-config.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<beans>
<bean id = "user" class="beans.User">bean>
beans>
beans>
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean id="userDao3" class="cn.itcast.spring.UserDaoImpl" />
<bean id="userDao4" class="cn.itcast.spring.UserDaoImpl" />
<bean id ="userService" class="cn.itcast.spring.UserServiceImpl">
bean>
beans>
pom.xml
<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.0modelVersion>
<groupId>org.examplegroupId>
<artifactId>spring1artifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.3.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>5.2.3.RELEASEversion>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>1.6.4version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
dependencies>
project>