1. Introdução às anotações comuns
No Spring, embora o uso de arquivos de configuração XML possa possibilitar a montagem de Beans, se o número de Beans na aplicação for grande, os arquivos de configuração XML ficarão muito inchados, o que trará certas dificuldades para manutenção e upgrades. Java fornece função de anotação (anotação) desde o JDK 5.0, e Spring também fornece suporte abrangente para tecnologia de anotação. Uma série de anotações é definida no Spring. A seguir, apresentaremos as anotações comumente usadas.
1. Anotações usadas para criar objetos
As anotações usadas para criar objetos são equivalentes a configurar <bean id = "" class = ""> </bean> em bean.xml
(1) @Component : Usado para armazenar o objeto de classe atual no container spring, e o atributo value é usado para especificar o id do bean. Quando não escrito, o valor padrão é o nome da classe atual e a primeira letra é minúscula.
(2) @Controller : geralmente atua na camada de controle (camada de controle), usada para identificar a classe da camada de controle como um Bean no Spring, e sua função é a mesma que @Component.
(3) @Service : geralmente atua na camada de negócios (camada de serviço), usada para identificar a classe da camada de negócios como um Bean no Spring, e sua função é a mesma que @Component.
(4) @Repository : Usado para identificar a classe da camada de acesso a dados (camada DAO) como um Bean no Spring, e sua função é a mesma que @Component.
(5) Explicação sobre o contexto: varredura de componentes :
1) Use o elemento component-scan do namespace de contexto para procurar anotações, e seu atributo de pacote básico é usado para notificar spring sobre os diretórios que precisam ser verificados. do seguinte modo:
<context:component-scan base-package="com.yht.example4"></context:component-scan>
2) Se você precisar escanear vários pacotes ao mesmo tempo, há duas maneiras de fazer isso:
Suponha que você queira verificar três pacotes de controlador, serviço e dao:
Método 1: use vírgulas para separar vários pacotes.
<context:component-scan base-package="com.yht.example4.controller,com.yht.example4.service,com.yht.example4.dao"></context:component-scan>
Método 2: Configure para verificar o mesmo diretório pai de vários pacotes.
<context:component-scan base-package="com.yht.example4"></context:component-scan>
3) Configure quais pacotes escanear em um determinado pacote - escaneie apenas o pacote do controlador e o pacote de serviço:
<!--
use-default-filters:设置为false,不使用默认的过滤规则。
include-filter:设置哪些包要扫描
-->
<context:component-scan base-package="com.yht.example4" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>
4) Configure quais pacotes não são escaneados em um determinado pacote - não escaneie o pacote do controlador
<!--
exclude-filter:设置哪些包不扫描
-->
<context:component-scan base-package="com.yht.example4" use-default-filters="false">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
(6) Caso: Simulando UserSerive para chamar UserDao, realizado por anotação
1) Configure o pacote para varredura de anotações em xml.
<context:component-scan base-package="com.yht.example4"></context:component-scan>
2) Crie UserService e IUserDao e sua classe de implementação UserDaoImpl e adicione anotações.
@Service
public class UserService {
@Autowired
private IUserDao userDao;
public void execute(){
System.out.println("service的execute()方法");
userDao.findUser();
}
}
public interface IUserDao {
void findUser();
}
@Repository
public class UserDaoImpl implements IUserDao {
@Override
public void findUser() {
System.out.println("UserImpl1 的findUser()");
}
}
3) Faça um teste.
@Test
public void testAnno(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean6.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.execute();
}
Os resultados da execução são os seguintes:
2. Anotações usadas para injetar valores
A anotação usada para injetar o valor é equivalente à operação de injetar o valor no objeto bean em bean.xml, <property name = "" value = ""> </property> ou <property name = "" ref = " "> </ propriedade>
(1) @Autowired : Usado para anotar as variáveis de atributo, definir métodos e construtores do Bean e cooperar com o processador de anotação correspondente para completar a configuração automática do Bean. A montagem é realizada de acordo com o tipo de Bean por default. Como no exemplo acima.
(2) @Qualifier : usado em conjunto com a anotação @Autowired, o assembly padrão por tipo de Bean será modificado para assembly pelo nome da instância do Bean, e o nome da instância do Bean é especificado pelo parâmetro do @Qualifier anotação.
No exemplo acima, se houver várias subclasses de IUserDao, @Autowired não será capaz de determinar qual subclasse escolher para injeção, então @Autowired e @Qualifier precisam ser usados juntos.
Ao adicionar duas classes de implementação dao, o seguinte erro será relatado neste momento:
Nenhum bean de qualificação do tipo 'com.yht.example4.dao.IUserDao' disponível: bean correspondente único esperado, mas encontrado 3: userDaoImpl, userImpl1, userImpl2。
Esse problema pode ser resolvido adicionando a anotação @Qualifier ao objeto userDao no serviço. do seguinte modo:
@Autowired
@Qualifier(value = "userImpl1")
private IUserDao userDao;
Os resultados da execução são os seguintes:
(3) @Resource : pode ser injetado por atributo ou por tipo. @Resource é fornecido por Java, não Spring. Use da seguinte maneira:
@Resource(name = "userImpl2")
private IUserDao userDao;
Os resultados da execução são os seguintes:
(4) @Value : Usado para injetar dados de tipo básico e tipo String. Adicione um atributo básico a userService: name, use @Value para injetar o valor e gerá-lo.
@Value("User Service")
private String name;
Os resultados são os seguintes:
3. Anotação para alterar o escopo de ação
@Scope : usado para especificar o escopo do bean, seu valor de atributo especifica o valor do escopo, valores comumente usados: singleton, prototype.
4. Usado para relacionado ao ciclo de vida
(1) @PreDestory : Usado para especificar o método de destruição.
(2) @PostConstruct : Usado para especificar o método de inicialização.
5. Outras novas notas
(1) @Configuration : A classe anotada é uma classe de configuração.
(2) @ComponentScan : Especifique o pacote que o Spring fará a varredura ao criar o contêiner por meio de anotações. A função de basePackages é a mesma, ambos são usados para especificar os pacotes a serem verificados ao criar um contêiner. Equivalente a <context: component-scan base-package = "com.day2"> </ context: component-scan> em XML
(3) @Import : Importar outras classes de configuração.
(4) @Bean : usado para armazenar o valor de retorno do método atual como um objeto de bean no contêiner ioc do spring
Dois, caso de desenvolvimento de anotação puro - nenhum arquivo de configuração
Simule uma arquitetura de três camadas: encontre usuários.
A estrutura do diretório é a seguinte:
1. A classe MySpringConfig é usada como a classe de configuração para substituir o arquivo xml original.
//作为配置类,代替xml
@Configuration
@ComponentScan("com.yht.example5")
public class MySpringConfig {
}
2. UserController da camada de controle
@Controller
public class UserController {
@Autowired
private IUserService userService;
public void isExist(){
System.out.println("controller层:判断用户是否存在");
userService.findUser();
}
}
3. O IUserService e as classes de implementação da camada de serviço.
public interface IUserService {
void findUser();
}
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao userDao;
@Override
public void findUser() {
System.out.println("service层:查找用户");
userDao.query();
}
}
4. IUserdao e classe de implementação da camada dao
public interface IUserDao {
void query();
}
@Repository
public class UserDaoImpl implements IUserDao {
@Override
public void query() {
System.out.println("dao层:数据库查询");
}
}
4. Teste de unidade
@Test
public void test(){
ApplicationContext context = new AnnotationConfigApplicationContext(MySpringConfig.class);
UserController userController = context.getBean("userController", UserController.class);
userController.isExist();
}
Os resultados são os seguintes: