Spring注解

今天来说一下Spring注解

注解是个好东西,但好东西我们也是看见过,整理过,理解过,用过才知道好。不求我们每个都记住,但求保有印象,在需要的时候能提取出来再查找相关资料,平时工作就不会显得那么被动了。

1.@Configuration注解

1.1@Configuration + <context>

该类等价 与XML中配置beans,相当于Ioc容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean,与xml中配置的bean意思一样。

@Configuration注解的类必需使用<context:component-scanbase-package=”XXX”/>扫描.如下:

例:

程序结构图:

(1)首先建立Perons.java,person实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.zk.Bean;
 
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
 
@Configuration
public class Person {
    public Person() {
        System.out.println("Person初始化");
    }
     
}

(2)其次在建立MainApp.java

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.zk.Main;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
import com.zk.Bean.Person;
 
public class MainApp {
    public static void main(String[]args)
    {
        ApplicationContext context = new AnnotationConfigApplicationContext(Person.class);
    }
}

(3)ApplicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 
<context:component-scan base-package="com.zk.Bean" />
</beans>

 运行结果:

1.2、@Configuration启动容器+@Bean注册Bean,@Bean下管理bean的生命周期

 

(1)首先建立TestBean.java,实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.zk.Bean;
 
import org.springframework.beans.factory.annotation.Value;
 
public class TestBean {
    @Value("zk")
    private String name;
    private String url;
    private String password;
     
     
    @Override
    public String toString() {
        return "TestBean [name=" + name + ", url=" + url + ", password="
                + password + "]";
    }
     
    public void sayHello(){
        System.out.println(name+":sayHello");
    }
     
    public void start(){
        System.out.println(name+":start");
    }
     
    public void cleanup(){
        System.out.println(name+":cleanup");
    }
}

(2)创建TestConfigure.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.zk.Bean;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
 
 
@Configuration
public class TestConfigure {
 
    public TestConfigure(){
        System.out.println("TestConfiguration...");
    }
     
     
    @Bean
    @Scope("prototype")
    TestBean testBean(){
        return new TestBean();
    }
}

 (3)创建ApplicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 
<context:component-scan base-package="com.zk.Bean" />
</beans>

  (4)创建TestMain.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.zk.Bean;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
public class TestMain {
    public static void main(String[]args)
    {
        // @Configuration注解的spring容器加载方式,用AnnotationConfigApplicationContext替换ClassPathXmlApplicationContext
        ApplicationContext context=new AnnotationConfigApplicationContext(TestConfigure.class);
         
         
        //获取bean
        TestBean tb=(TestBean) context.getBean("testBean");
        tb.sayHello();
    }
}

运行结果如下:

2.@Value注解

在程序中使用@Value的注解是为了给变量赋值,如上面的注解:

1
2
@Value("zk")
private String name;

  使用

1
2
3
4
5
// @Configuration注解的spring容器加载方式,用AnnotationConfigApplicationContext替换ClassPathXmlApplicationContext
ApplicationContext context=new AnnotationConfigApplicationContext(TestConfigure.class);
//获取bean
TestBean tb=(TestBean) context.getBean("testBean");
tb.sayHello();

  调用getBean()方法可以获取到name的值。

3. @Controller, @Service, @Repository,@Component

目前4种注解意思是一样,并没有什么区别,区别只是名字不同。使用方法:

(1)创建com.zk.component,创建TestObject.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.zk.component;
 
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
 
import org.springframework.stereotype.Component;
 
 
@Component
public class TestObject {
    @PostConstruct 
    public void contructbefore(){
        System.out.println("初始化之前的操作");
    }
     
    @PreDestroy
    public void contructAfter(){
        System.out.println("初始化之后的操作");
    }
}

 (2)创建com.zk.controller,并创建UserController.java

1
2
3
4
5
6
7
8
9
10
11
package com.zk.controller;
 
import org.springframework.stereotype.Controller;
 
 
@Controller
public class UserController {
    public void execute(){
        System.out.println("UserController execute...");
    }
}

 (3)创建com.zk.Service,并创建UserService.java

1
2
3
4
5
6
7
8
9
10
11
12
package com.zk.service;
 
import org.springframework.stereotype.Service;
 
 
@Service
public class UserService {
     
    public void add(){
        System.out.println("UserService add..");
    }
}

(4)创建com.zk.Repository,并创建UserRepository.java和UserRepositoryImpl.java

1
2
3
4
5
6
package com.zk.UserRepository;
 
 
public interface UserRepository {
    public void save();
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.zk.UserRepository;
 
import org.springframework.stereotype.Repository;
 
@Repository("userRepository")
public class UserRepositoryImpl implements UserRepository{
 
    @Override
    public void save() {
        // TODO Auto-generated method stub
        System.out.println("UserRepository save");
    }
     
}

(5)最后,实现MainAPP实现类:

MainAPP.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package Main;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.zk.UserRepository.UserRepository;
import com.zk.component.TestObject;
import com.zk.controller.UserController;
import com.zk.service.UserService;
 
public class MainAPP {
    public static void main(String[]args)
    {
        ApplicationContext ac=new ClassPathXmlApplicationContext("ApplicationContext.xml");
        TestObject to=(TestObject) ac.getBean("testObject");
        System.out.println(to.toString());
         
        UserService us=(UserService) ac.getBean("userService");
        us.add();
         
        UserRepository ur=(UserRepository)ac.getBean("userRepository");
        ur.save();
         
        UserController uc=(UserController)ac.getBean("userController");
        uc.execute();
    }
}

 ApplicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 
  
<context:component-scan base-package="com.zk.controller" />
<context:component-scan base-package="com.zk.component" />
<context:component-scan base-package="com.zk.UserRepository" />
<context:component-scan base-package="com.zk.service" />
</beans>

 执行Main后结果如下:

 

4. @PostConstruct 和 @PreDestory

实现初始化和销毁bean之前进行的操作,只能有一个方法可以用此注释进行注释,方法不能有参数,返回值必需是void,方法需要是非静态的。

TestObject.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.zk.component;
 
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
 
import org.springframework.stereotype.Component;
 
 
@Component
public class TestObject {
    @PostConstruct 
    public void contructbefore(){
        System.out.println("初始化之前的操作");
    }
     
    @PreDestroy
    public void contructAfter(){
        System.out.println("初始化之后的操作");
    }
}

 MainAPP.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package Main;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zk.component.TestObject;
public class MainAPP {
    public static void main(String[]args)
    {
        AbstractApplicationContext ac=new ClassPathXmlApplicationContext("ApplicationContext.xml");
        TestObject to=(TestObject) ac.getBean("testObject");
        System.out.println(to.toString());     
        ((AbstractApplicationContext) ac).close();
    }
}

 applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 
  
 
 <context:component-scan base-package="com.zk.component" />
</beans>

 执行结果如下:

 

@PostConstruct:在构造方法和init方法(如果有的话)之间得到调用,且只会执行一次。

@PreDestory:注解的方法在destory()方法调用后得到执行。

 

引深一点,Spring 容器中的 Bean 是有生命周期的,Spring 允许在 Bean 在初始化完成后以及 Bean 销毁前执行特定的操作,常用的设定方式有以下三种:

1.通过实现 InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法;

2.通过 <bean> 元素的 init-method/destroy-method属性指定初始化之后 /销毁之前调用的操作方法;

3.在指定方法上加上@PostConstruct 或@PreDestroy注解来制定该方法是在初始化之后还是销毁之前调用

但他们之前并不等价。即使3个方法都用上了,也有先后顺序.

Constructor > @PostConstruct >InitializingBean > init-method

5. @Autowired,@Qualifier

@Autowired是用在JavaBean中的注解,默认通过byType形式查找Bean,如果发现多个Bean,则使用byName形式查找Bean,用来给指定的字段或方法注入所需的外部资源。 

可以手动使用@Qualifier注解给需要通过byName形式查找的Bean进行赋值,例如

1
2
3
@Autowired
@Qualifier(“pean”)
public Fruit fruit; 

 

 

UserDao.java

1
2
3
4
5
package com.zk.dao;
 
public interface UserDao {
    public void sayHello();
}

 UserDaoImpl.java

1
2
3
4
5
6
7
8
9
10
11
package com.zk.dao;
 
import org.springframework.stereotype.Repository;
 
@Repository("UserDao")
public class UserDaoImpl implements UserDao{
     
    public void sayHello(){
        System.out.println("userdao hello");
    }
}

 UserService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.zk.service;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import com.zk.dao.UserDao;
 
@Service
public class UserService {
    @Autowired
    private UserDao userdao;
     
    public void sayHello(){
    userdao.sayHello();
    }
}

 Main.App

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package Main;
 
import org.springframework.context.ApplicationContext;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.zk.service.UserService;
 
public class MainApp {
    public static void main(String[]args)
    {
        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService object = (UserService) ctx.getBean("userService");
        object.sayHello();
    }
}

 执行MainApp

 

6. @Primary

 

(1)首先创建fruit接口,并建立继承fruit接口的两个子类Apple.java,Pear.java,在Pear.java中添加@Primary,将Pear类设为优先。

fruit.java

1
2
3
4
5
6
7
8
package com.zk.mybean;
 
import org.springframework.stereotype.Component;
 
 
public interface fruit {
    public void sayHello();
}

Apple.java

1
2
3
4
5
6
7
8
9
10
11
12
package com.zk.mybean;
 
import org.springframework.stereotype.Component;
 
 
 
@Component
public class Apple implements fruit{
    public void sayHello(){
        System.out.println("Apple Hello");
    }
}

 Pear.java

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.zk.mybean;
 
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
 
 
@Component
@Primary
public class Pear implements fruit{
    public void sayHello(){
        System.out.println("Pear Hello");
    }
}

 (2)创建fruitService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.zk.myservice;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import com.zk.mybean.fruit;
@Service
public class fruitService {
     
    @Autowired
    public fruit fruit;
     
    public void getfruit(){
        fruit.sayHello();
    }
     
}

 (3)最后,实现MainAPP.java和ApplicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package Main;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.zk.mybean.fruit;
import com.zk.myservice.fruitService;
 
public class MainAPP {
    public static void main(String[]args)
    {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        fruitService fs=(fruitService) ac.getBean(fruitService.class);
        fs.getfruit();
    }
}

 执行结果如下:

 

posted @   leagueandlegends  阅读(199)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示